migrate opengl and system from  development/tools

- components under system are moved one directory up like all other HALs

Change-Id: I03b870b870d83b247ac398cadfb155f03c9adfa0
diff --git a/camera/Android.mk b/camera/Android.mk
new file mode 100755
index 0000000..2428092
--- /dev/null
+++ b/camera/Android.mk
@@ -0,0 +1,72 @@
+# Copyright (C) 2011 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.
+
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
+LOCAL_CFLAGS += -fno-short-enums -DQEMU_HARDWARE
+LOCAL_SHARED_LIBRARIES:= \
+    libbinder \
+    libutils \
+    libcutils \
+    libcamera_client \
+    libui \
+
+# JPEG conversion libraries and includes.
+LOCAL_SHARED_LIBRARIES += \
+	libjpeg \
+	libskia \
+	libandroid_runtime \
+	libcamera_metadata
+
+LOCAL_C_INCLUDES += external/jpeg \
+	external/skia/include/core/ \
+	frameworks/native/include/media/hardware \
+	frameworks/base/core/jni/android/graphics \
+	$(LOCAL_PATH)/../opengl/system/OpenglSystemCommon \
+	$(call include-path-for, camera)
+
+LOCAL_SRC_FILES := \
+	EmulatedCameraHal.cpp \
+    EmulatedCameraFactory.cpp \
+    EmulatedBaseCamera.cpp \
+    EmulatedCamera.cpp \
+	EmulatedCameraDevice.cpp \
+	EmulatedQemuCamera.cpp \
+	EmulatedQemuCameraDevice.cpp \
+	EmulatedFakeCamera.cpp \
+	EmulatedFakeCameraDevice.cpp \
+	Converters.cpp \
+	PreviewWindow.cpp \
+	CallbackNotifier.cpp \
+	QemuClient.cpp \
+	JpegCompressor.cpp \
+    EmulatedCamera2.cpp \
+	EmulatedFakeCamera2.cpp \
+	EmulatedQemuCamera2.cpp \
+	fake-pipeline2/Scene.cpp \
+	fake-pipeline2/Sensor.cpp \
+	fake-pipeline2/JpegCompressor.cpp
+
+
+ifeq ($(TARGET_PRODUCT),vbox_x86)
+LOCAL_MODULE := camera.vbox_x86
+else
+LOCAL_MODULE := camera.goldfish
+endif
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/camera/CallbackNotifier.cpp b/camera/CallbackNotifier.cpp
new file mode 100755
index 0000000..140c872
--- /dev/null
+++ b/camera/CallbackNotifier.cpp
@@ -0,0 +1,294 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+/*
+ * Contains implementation of a class CallbackNotifier that manages callbacks set
+ * via set_callbacks, enable_msg_type, and disable_msg_type camera HAL API.
+ */
+
+#define LOG_NDEBUG 0
+#define LOG_TAG "EmulatedCamera_CallbackNotifier"
+#include <cutils/log.h>
+#include <MetadataBufferType.h>
+#include "EmulatedCameraDevice.h"
+#include "CallbackNotifier.h"
+#include "JpegCompressor.h"
+
+namespace android {
+
+/* String representation of camera messages. */
+static const char* lCameraMessages[] =
+{
+    "CAMERA_MSG_ERROR",
+    "CAMERA_MSG_SHUTTER",
+    "CAMERA_MSG_FOCUS",
+    "CAMERA_MSG_ZOOM",
+    "CAMERA_MSG_PREVIEW_FRAME",
+    "CAMERA_MSG_VIDEO_FRAME",
+    "CAMERA_MSG_POSTVIEW_FRAME",
+    "CAMERA_MSG_RAW_IMAGE",
+    "CAMERA_MSG_COMPRESSED_IMAGE",
+    "CAMERA_MSG_RAW_IMAGE_NOTIFY",
+    "CAMERA_MSG_PREVIEW_METADATA"
+};
+static const int lCameraMessagesNum = sizeof(lCameraMessages) / sizeof(char*);
+
+/* Builds an array of strings for the given set of messages.
+ * Param:
+ *  msg - Messages to get strings for,
+ *  strings - Array where to save strings
+ *  max - Maximum number of entries in the array.
+ * Return:
+ *  Number of strings saved into the 'strings' array.
+ */
+static int GetMessageStrings(uint32_t msg, const char** strings, int max)
+{
+    int index = 0;
+    int out = 0;
+    while (msg != 0 && out < max && index < lCameraMessagesNum) {
+        while ((msg & 0x1) == 0 && index < lCameraMessagesNum) {
+            msg >>= 1;
+            index++;
+        }
+        if ((msg & 0x1) != 0 && index < lCameraMessagesNum) {
+            strings[out] = lCameraMessages[index];
+            out++;
+            msg >>= 1;
+            index++;
+        }
+    }
+
+    return out;
+}
+
+/* Logs messages, enabled by the mask. */
+static void PrintMessages(uint32_t msg)
+{
+    const char* strs[lCameraMessagesNum];
+    const int translated = GetMessageStrings(msg, strs, lCameraMessagesNum);
+    for (int n = 0; n < translated; n++) {
+        ALOGV("    %s", strs[n]);
+    }
+}
+
+CallbackNotifier::CallbackNotifier()
+    : mNotifyCB(NULL),
+      mDataCB(NULL),
+      mDataCBTimestamp(NULL),
+      mGetMemoryCB(NULL),
+      mCBOpaque(NULL),
+      mLastFrameTimestamp(0),
+      mFrameRefreshFreq(0),
+      mMessageEnabler(0),
+      mJpegQuality(90),
+      mVideoRecEnabled(false),
+      mTakingPicture(false)
+{
+}
+
+CallbackNotifier::~CallbackNotifier()
+{
+}
+
+/****************************************************************************
+ * Camera API
+ ***************************************************************************/
+
+void CallbackNotifier::setCallbacks(camera_notify_callback notify_cb,
+                                    camera_data_callback data_cb,
+                                    camera_data_timestamp_callback data_cb_timestamp,
+                                    camera_request_memory get_memory,
+                                    void* user)
+{
+    ALOGV("%s: %p, %p, %p, %p (%p)",
+         __FUNCTION__, notify_cb, data_cb, data_cb_timestamp, get_memory, user);
+
+    Mutex::Autolock locker(&mObjectLock);
+    mNotifyCB = notify_cb;
+    mDataCB = data_cb;
+    mDataCBTimestamp = data_cb_timestamp;
+    mGetMemoryCB = get_memory;
+    mCBOpaque = user;
+}
+
+void CallbackNotifier::enableMessage(uint msg_type)
+{
+    ALOGV("%s: msg_type = 0x%x", __FUNCTION__, msg_type);
+    PrintMessages(msg_type);
+
+    Mutex::Autolock locker(&mObjectLock);
+    mMessageEnabler |= msg_type;
+    ALOGV("**** Currently enabled messages:");
+    PrintMessages(mMessageEnabler);
+}
+
+void CallbackNotifier::disableMessage(uint msg_type)
+{
+    ALOGV("%s: msg_type = 0x%x", __FUNCTION__, msg_type);
+    PrintMessages(msg_type);
+
+    Mutex::Autolock locker(&mObjectLock);
+    mMessageEnabler &= ~msg_type;
+    ALOGV("**** Currently enabled messages:");
+    PrintMessages(mMessageEnabler);
+}
+
+status_t CallbackNotifier::enableVideoRecording(int fps)
+{
+    ALOGV("%s: FPS = %d", __FUNCTION__, fps);
+
+    Mutex::Autolock locker(&mObjectLock);
+    mVideoRecEnabled = true;
+    mLastFrameTimestamp = 0;
+    mFrameRefreshFreq = 1000000000LL / fps;
+
+    return NO_ERROR;
+}
+
+void CallbackNotifier::disableVideoRecording()
+{
+    ALOGV("%s:", __FUNCTION__);
+
+    Mutex::Autolock locker(&mObjectLock);
+    mVideoRecEnabled = false;
+    mLastFrameTimestamp = 0;
+    mFrameRefreshFreq = 0;
+}
+
+void CallbackNotifier::releaseRecordingFrame(const void* opaque)
+{
+    /* We don't really have anything to release here, since we report video
+     * frames by copying them directly to the camera memory. */
+}
+
+status_t CallbackNotifier::storeMetaDataInBuffers(bool enable)
+{
+    /* Return INVALID_OPERATION means HAL does not support metadata. So HAL will
+     * return actual frame data with CAMERA_MSG_VIDEO_FRRAME. Return
+     * INVALID_OPERATION to mean metadata is not supported. */
+    return INVALID_OPERATION;
+}
+
+/****************************************************************************
+ * Public API
+ ***************************************************************************/
+
+void CallbackNotifier::cleanupCBNotifier()
+{
+    Mutex::Autolock locker(&mObjectLock);
+    mMessageEnabler = 0;
+    mNotifyCB = NULL;
+    mDataCB = NULL;
+    mDataCBTimestamp = NULL;
+    mGetMemoryCB = NULL;
+    mCBOpaque = NULL;
+    mLastFrameTimestamp = 0;
+    mFrameRefreshFreq = 0;
+    mJpegQuality = 90;
+    mVideoRecEnabled = false;
+    mTakingPicture = false;
+}
+
+void CallbackNotifier::onNextFrameAvailable(const void* frame,
+                                            nsecs_t timestamp,
+                                            EmulatedCameraDevice* camera_dev)
+{
+    if (isMessageEnabled(CAMERA_MSG_VIDEO_FRAME) && isVideoRecordingEnabled() &&
+            isNewVideoFrameTime(timestamp)) {
+        camera_memory_t* cam_buff =
+            mGetMemoryCB(-1, camera_dev->getFrameBufferSize(), 1, NULL);
+        if (NULL != cam_buff && NULL != cam_buff->data) {
+            memcpy(cam_buff->data, frame, camera_dev->getFrameBufferSize());
+            mDataCBTimestamp(timestamp, CAMERA_MSG_VIDEO_FRAME,
+                               cam_buff, 0, mCBOpaque);
+        } else {
+            ALOGE("%s: Memory failure in CAMERA_MSG_VIDEO_FRAME", __FUNCTION__);
+        }
+    }
+
+    if (isMessageEnabled(CAMERA_MSG_PREVIEW_FRAME)) {
+        camera_memory_t* cam_buff =
+            mGetMemoryCB(-1, camera_dev->getFrameBufferSize(), 1, NULL);
+        if (NULL != cam_buff && NULL != cam_buff->data) {
+            memcpy(cam_buff->data, frame, camera_dev->getFrameBufferSize());
+            mDataCB(CAMERA_MSG_PREVIEW_FRAME, cam_buff, 0, NULL, mCBOpaque);
+            cam_buff->release(cam_buff);
+        } else {
+            ALOGE("%s: Memory failure in CAMERA_MSG_PREVIEW_FRAME", __FUNCTION__);
+        }
+    }
+
+    if (mTakingPicture) {
+        /* This happens just once. */
+        mTakingPicture = false;
+        /* The sequence of callbacks during picture taking is:
+         *  - CAMERA_MSG_SHUTTER
+         *  - CAMERA_MSG_RAW_IMAGE_NOTIFY
+         *  - CAMERA_MSG_COMPRESSED_IMAGE
+         */
+        if (isMessageEnabled(CAMERA_MSG_SHUTTER)) {
+            mNotifyCB(CAMERA_MSG_SHUTTER, 0, 0, mCBOpaque);
+        }
+        if (isMessageEnabled(CAMERA_MSG_RAW_IMAGE_NOTIFY)) {
+            mNotifyCB(CAMERA_MSG_RAW_IMAGE_NOTIFY, 0, 0, mCBOpaque);
+        }
+        if (isMessageEnabled(CAMERA_MSG_COMPRESSED_IMAGE)) {
+            /* Compress the frame to JPEG. Note that when taking pictures, we
+             * have requested camera device to provide us with NV21 frames. */
+            NV21JpegCompressor compressor;
+            status_t res =
+                compressor.compressRawImage(frame, camera_dev->getFrameWidth(),
+                                            camera_dev->getFrameHeight(),
+                                            mJpegQuality);
+            if (res == NO_ERROR) {
+                camera_memory_t* jpeg_buff =
+                    mGetMemoryCB(-1, compressor.getCompressedSize(), 1, NULL);
+                if (NULL != jpeg_buff && NULL != jpeg_buff->data) {
+                    compressor.getCompressedImage(jpeg_buff->data);
+                    mDataCB(CAMERA_MSG_COMPRESSED_IMAGE, jpeg_buff, 0, NULL, mCBOpaque);
+                    jpeg_buff->release(jpeg_buff);
+                } else {
+                    ALOGE("%s: Memory failure in CAMERA_MSG_VIDEO_FRAME", __FUNCTION__);
+                }
+            } else {
+                ALOGE("%s: Compression failure in CAMERA_MSG_VIDEO_FRAME", __FUNCTION__);
+            }
+        }
+    }
+}
+
+void CallbackNotifier::onCameraDeviceError(int err)
+{
+    if (isMessageEnabled(CAMERA_MSG_ERROR) && mNotifyCB != NULL) {
+        mNotifyCB(CAMERA_MSG_ERROR, err, 0, mCBOpaque);
+    }
+}
+
+/****************************************************************************
+ * Private API
+ ***************************************************************************/
+
+bool CallbackNotifier::isNewVideoFrameTime(nsecs_t timestamp)
+{
+    Mutex::Autolock locker(&mObjectLock);
+    if ((timestamp - mLastFrameTimestamp) >= mFrameRefreshFreq) {
+        mLastFrameTimestamp = timestamp;
+        return true;
+    }
+    return false;
+}
+
+}; /* namespace android */
diff --git a/camera/CallbackNotifier.h b/camera/CallbackNotifier.h
new file mode 100755
index 0000000..63301d2
--- /dev/null
+++ b/camera/CallbackNotifier.h
@@ -0,0 +1,233 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef HW_EMULATOR_CAMERA_CALLBACK_NOTIFIER_H
+#define HW_EMULATOR_CAMERA_CALLBACK_NOTIFIER_H
+
+/*
+ * Contains declaration of a class CallbackNotifier that manages callbacks set
+ * via set_callbacks, enable_msg_type, and disable_msg_type camera HAL API.
+ */
+
+namespace android {
+
+class EmulatedCameraDevice;
+
+/* Manages callbacks set via set_callbacks, enable_msg_type, and disable_msg_type
+ * camera HAL API.
+ *
+ * Objects of this class are contained in EmulatedCamera objects, and handle
+ * relevant camera API callbacks.
+ * Locking considerations. Apparently, it's not allowed to call callbacks
+ * registered in this class, while holding a lock: recursion is quite possible,
+ * which will cause a deadlock.
+ */
+class CallbackNotifier {
+public:
+    /* Constructs CallbackNotifier instance. */
+    CallbackNotifier();
+
+    /* Destructs CallbackNotifier instance. */
+    ~CallbackNotifier();
+
+    /****************************************************************************
+     * Camera API
+     ***************************************************************************/
+
+public:
+    /* Actual handler for camera_device_ops_t::set_callbacks callback.
+     * This method is called by the containing emulated camera object when it is
+     * handing the camera_device_ops_t::set_callbacks callback.
+     */
+    void setCallbacks(camera_notify_callback notify_cb,
+                      camera_data_callback data_cb,
+                      camera_data_timestamp_callback data_cb_timestamp,
+                      camera_request_memory get_memory,
+                      void* user);
+
+    /* Actual handler for camera_device_ops_t::enable_msg_type callback.
+     * This method is called by the containing emulated camera object when it is
+     * handing the camera_device_ops_t::enable_msg_type callback.
+     */
+    void enableMessage(uint msg_type);
+
+    /* Actual handler for camera_device_ops_t::disable_msg_type callback.
+     * This method is called by the containing emulated camera object when it is
+     * handing the camera_device_ops_t::disable_msg_type callback.
+     */
+    void disableMessage(uint msg_type);
+
+    /* Actual handler for camera_device_ops_t::store_meta_data_in_buffers
+     * callback. This method is called by the containing emulated camera object
+     * when it is handing the camera_device_ops_t::store_meta_data_in_buffers
+     * callback.
+     * Return:
+     *  NO_ERROR on success, or an appropriate error status.
+     */
+    status_t storeMetaDataInBuffers(bool enable);
+
+    /* Enables video recording.
+     * This method is called by the containing emulated camera object when it is
+     * handing the camera_device_ops_t::start_recording callback.
+     * Param:
+     *  fps - Video frame frequency. This parameter determins when a frame
+     *      received via onNextFrameAvailable call will be pushed through the
+     *      callback.
+     * Return:
+     *  NO_ERROR on success, or an appropriate error status.
+     */
+    status_t enableVideoRecording(int fps);
+
+    /* Disables video recording.
+     * This method is called by the containing emulated camera object when it is
+     * handing the camera_device_ops_t::stop_recording callback.
+     */
+    void disableVideoRecording();
+
+    /* Releases video frame, sent to the framework.
+     * This method is called by the containing emulated camera object when it is
+     * handing the camera_device_ops_t::release_recording_frame callback.
+     */
+    void releaseRecordingFrame(const void* opaque);
+
+    /* Actual handler for camera_device_ops_t::msg_type_enabled callback.
+     * This method is called by the containing emulated camera object when it is
+     * handing the camera_device_ops_t::msg_type_enabled callback.
+     * Note: this method doesn't grab a lock while checking message status, since
+     * upon exit the status would be undefined anyway. So, grab a lock before
+     * calling this method if you care about persisting a defined message status.
+     * Return:
+     *  0 if message is disabled, or non-zero value, if message is enabled.
+     */
+    inline int isMessageEnabled(uint msg_type)
+    {
+        return mMessageEnabler & msg_type;
+    }
+
+    /* Checks id video recording is enabled.
+     * This method is called by the containing emulated camera object when it is
+     * handing the camera_device_ops_t::recording_enabled callback.
+     * Note: this method doesn't grab a lock while checking video recordin status,
+     * since upon exit the status would be undefined anyway. So, grab a lock
+     * before calling this method if you care about persisting of a defined video
+     * recording status.
+     * Return:
+     *  true if video recording is enabled, or false if it is disabled.
+     */
+    inline bool isVideoRecordingEnabled()
+    {
+        return mVideoRecEnabled;
+    }
+
+    /****************************************************************************
+     * Public API
+     ***************************************************************************/
+
+public:
+    /* Resets the callback notifier. */
+    void cleanupCBNotifier();
+
+    /* Next frame is available in the camera device.
+     * This is a notification callback that is invoked by the camera device when
+     * a new frame is available.
+     * Note that most likely this method is called in context of a worker thread
+     * that camera device has created for frame capturing.
+     * Param:
+     *  frame - Captured frame, or NULL if camera device didn't pull the frame
+     *      yet. If NULL is passed in this parameter use GetCurrentFrame method
+     *      of the camera device class to obtain the next frame. Also note that
+     *      the size of the frame that is passed here (as well as the frame
+     *      returned from the GetCurrentFrame method) is defined by the current
+     *      frame settings (width + height + pixel format) for the camera device.
+     * timestamp - Frame's timestamp.
+     * camera_dev - Camera device instance that delivered the frame.
+     */
+    void onNextFrameAvailable(const void* frame,
+                              nsecs_t timestamp,
+                              EmulatedCameraDevice* camera_dev);
+
+    /* Entry point for notifications that occur in camera device.
+     * Param:
+     *  err - CAMERA_ERROR_XXX error code.
+     */
+    void onCameraDeviceError(int err);
+
+    /* Sets, or resets taking picture state.
+     * This state control whether or not to notify the framework about compressed
+     * image, shutter, and other picture related events.
+     */
+    void setTakingPicture(bool taking)
+    {
+        mTakingPicture = taking;
+    }
+
+    /* Sets JPEG quality used to compress frame during picture taking. */
+    void setJpegQuality(int jpeg_quality)
+    {
+        mJpegQuality = jpeg_quality;
+    }
+
+    /****************************************************************************
+     * Private API
+     ***************************************************************************/
+
+protected:
+    /* Checks if it's time to push new video frame.
+     * Note that this method must be called while object is locked.
+     * Param:
+     *  timestamp - Timestamp for the new frame. */
+    bool isNewVideoFrameTime(nsecs_t timestamp);
+
+    /****************************************************************************
+     * Data members
+     ***************************************************************************/
+
+protected:
+    /* Locks this instance for data change. */
+    Mutex                           mObjectLock;
+
+    /*
+     * Callbacks, registered in set_callbacks.
+     */
+
+    camera_notify_callback          mNotifyCB;
+    camera_data_callback            mDataCB;
+    camera_data_timestamp_callback  mDataCBTimestamp;
+    camera_request_memory           mGetMemoryCB;
+    void*                           mCBOpaque;
+
+    /* Timestamp when last frame has been delivered to the framework. */
+    nsecs_t                         mLastFrameTimestamp;
+
+    /* Video frequency in nanosec. */
+    nsecs_t                         mFrameRefreshFreq;
+
+    /* Message enabler. */
+    uint32_t                        mMessageEnabler;
+
+    /* JPEG quality used to compress frame during picture taking. */
+    int                             mJpegQuality;
+
+    /* Video recording status. */
+    bool                            mVideoRecEnabled;
+
+    /* Picture taking status. */
+    bool                            mTakingPicture;
+};
+
+}; /* namespace android */
+
+#endif  /* HW_EMULATOR_CAMERA_CALLBACK_NOTIFIER_H */
diff --git a/camera/Converters.cpp b/camera/Converters.cpp
new file mode 100755
index 0000000..f63f67f
--- /dev/null
+++ b/camera/Converters.cpp
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+/*
+ * Contains implemenation of framebuffer conversion routines.
+ */
+
+#define LOG_NDEBUG 0
+#define LOG_TAG "EmulatedCamera_Converter"
+#include <cutils/log.h>
+#include "Converters.h"
+
+namespace android {
+
+static void _YUV420SToRGB565(const uint8_t* Y,
+                             const uint8_t* U,
+                             const uint8_t* V,
+                             int dUV,
+                             uint16_t* rgb,
+                             int width,
+                             int height)
+{
+    const uint8_t* U_pos = U;
+    const uint8_t* V_pos = V;
+
+    for (int y = 0; y < height; y++) {
+        for (int x = 0; x < width; x += 2, U += dUV, V += dUV) {
+            const uint8_t nU = *U;
+            const uint8_t nV = *V;
+            *rgb = YUVToRGB565(*Y, nU, nV);
+            Y++; rgb++;
+            *rgb = YUVToRGB565(*Y, nU, nV);
+            Y++; rgb++;
+        }
+        if (y & 0x1) {
+            U_pos = U;
+            V_pos = V;
+        } else {
+            U = U_pos;
+            V = V_pos;
+        }
+    }
+}
+
+static void _YUV420SToRGB32(const uint8_t* Y,
+                            const uint8_t* U,
+                            const uint8_t* V,
+                            int dUV,
+                            uint32_t* rgb,
+                            int width,
+                            int height)
+{
+    const uint8_t* U_pos = U;
+    const uint8_t* V_pos = V;
+
+    for (int y = 0; y < height; y++) {
+        for (int x = 0; x < width; x += 2, U += dUV, V += dUV) {
+            const uint8_t nU = *U;
+            const uint8_t nV = *V;
+            *rgb = YUVToRGB32(*Y, nU, nV);
+            Y++; rgb++;
+            *rgb = YUVToRGB32(*Y, nU, nV);
+            Y++; rgb++;
+        }
+        if (y & 0x1) {
+            U_pos = U;
+            V_pos = V;
+        } else {
+            U = U_pos;
+            V = V_pos;
+        }
+    }
+}
+
+void YV12ToRGB565(const void* yv12, void* rgb, int width, int height)
+{
+    const int pix_total = width * height;
+    const uint8_t* Y = reinterpret_cast<const uint8_t*>(yv12);
+    const uint8_t* U = Y + pix_total;
+    const uint8_t* V = U + pix_total / 4;
+    _YUV420SToRGB565(Y, U, V, 1, reinterpret_cast<uint16_t*>(rgb), width, height);
+}
+
+void YV12ToRGB32(const void* yv12, void* rgb, int width, int height)
+{
+    const int pix_total = width * height;
+    const uint8_t* Y = reinterpret_cast<const uint8_t*>(yv12);
+    const uint8_t* V = Y + pix_total;
+    const uint8_t* U = V + pix_total / 4;
+    _YUV420SToRGB32(Y, U, V, 1, reinterpret_cast<uint32_t*>(rgb), width, height);
+}
+
+void YU12ToRGB32(const void* yu12, void* rgb, int width, int height)
+{
+    const int pix_total = width * height;
+    const uint8_t* Y = reinterpret_cast<const uint8_t*>(yu12);
+    const uint8_t* U = Y + pix_total;
+    const uint8_t* V = U + pix_total / 4;
+    _YUV420SToRGB32(Y, U, V, 1, reinterpret_cast<uint32_t*>(rgb), width, height);
+}
+
+/* Common converter for YUV 4:2:0 interleaved to RGB565.
+ * y, u, and v point to Y,U, and V panes, where U and V values are interleaved.
+ */
+static void _NVXXToRGB565(const uint8_t* Y,
+                          const uint8_t* U,
+                          const uint8_t* V,
+                          uint16_t* rgb,
+                          int width,
+                          int height)
+{
+    _YUV420SToRGB565(Y, U, V, 2, rgb, width, height);
+}
+
+/* Common converter for YUV 4:2:0 interleaved to RGB32.
+ * y, u, and v point to Y,U, and V panes, where U and V values are interleaved.
+ */
+static void _NVXXToRGB32(const uint8_t* Y,
+                         const uint8_t* U,
+                         const uint8_t* V,
+                         uint32_t* rgb,
+                         int width,
+                         int height)
+{
+    _YUV420SToRGB32(Y, U, V, 2, rgb, width, height);
+}
+
+void NV12ToRGB565(const void* nv12, void* rgb, int width, int height)
+{
+    const int pix_total = width * height;
+    const uint8_t* y = reinterpret_cast<const uint8_t*>(nv12);
+    _NVXXToRGB565(y, y + pix_total, y + pix_total + 1,
+                  reinterpret_cast<uint16_t*>(rgb), width, height);
+}
+
+void NV12ToRGB32(const void* nv12, void* rgb, int width, int height)
+{
+    const int pix_total = width * height;
+    const uint8_t* y = reinterpret_cast<const uint8_t*>(nv12);
+    _NVXXToRGB32(y, y + pix_total, y + pix_total + 1,
+                 reinterpret_cast<uint32_t*>(rgb), width, height);
+}
+
+void NV21ToRGB565(const void* nv21, void* rgb, int width, int height)
+{
+    const int pix_total = width * height;
+    const uint8_t* y = reinterpret_cast<const uint8_t*>(nv21);
+    _NVXXToRGB565(y, y + pix_total + 1, y + pix_total,
+                  reinterpret_cast<uint16_t*>(rgb), width, height);
+}
+
+void NV21ToRGB32(const void* nv21, void* rgb, int width, int height)
+{
+    const int pix_total = width * height;
+    const uint8_t* y = reinterpret_cast<const uint8_t*>(nv21);
+    _NVXXToRGB32(y, y + pix_total + 1, y + pix_total,
+                 reinterpret_cast<uint32_t*>(rgb), width, height);
+}
+
+}; /* namespace android */
diff --git a/camera/Converters.h b/camera/Converters.h
new file mode 100755
index 0000000..13e2a85
--- /dev/null
+++ b/camera/Converters.h
@@ -0,0 +1,314 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef HW_EMULATOR_CAMERA_CONVERTERS_H
+#define HW_EMULATOR_CAMERA_CONVERTERS_H
+
+#include <endian.h>
+
+#ifndef __BYTE_ORDER
+#error "could not determine byte order"
+#endif
+
+/*
+ * Contains declaration of framebuffer conversion routines.
+ *
+ * NOTE: RGB and big/little endian considerations. Wherewer in this code RGB
+ * pixels are represented as WORD, or DWORD, the color order inside the
+ * WORD / DWORD matches the one that would occur if that WORD / DWORD would have
+ * been read from the typecasted framebuffer:
+ *
+ *      const uint32_t rgb = *reinterpret_cast<const uint32_t*>(framebuffer);
+ *
+ * So, if this code runs on the little endian CPU, red color in 'rgb' would be
+ * masked as 0x000000ff, and blue color would be masked as 0x00ff0000, while if
+ * the code runs on a big endian CPU, the red color in 'rgb' would be masked as
+ * 0xff000000, and blue color would be masked as 0x0000ff00,
+ */
+
+namespace android {
+
+/*
+ * RGB565 color masks
+ */
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+static const uint16_t kRed5     = 0x001f;
+static const uint16_t kGreen6   = 0x07e0;
+static const uint16_t kBlue5    = 0xf800;
+#else   // __BYTE_ORDER
+static const uint16_t kRed5     = 0xf800;
+static const uint16_t kGreen6   = 0x07e0;
+static const uint16_t kBlue5    = 0x001f;
+#endif  // __BYTE_ORDER
+static const uint32_t kBlack16  = 0x0000;
+static const uint32_t kWhite16  = kRed5 | kGreen6 | kBlue5;
+
+/*
+ * RGB32 color masks
+ */
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+static const uint32_t kRed8     = 0x000000ff;
+static const uint32_t kGreen8   = 0x0000ff00;
+static const uint32_t kBlue8    = 0x00ff0000;
+#else   // __BYTE_ORDER
+static const uint32_t kRed8     = 0x00ff0000;
+static const uint32_t kGreen8   = 0x0000ff00;
+static const uint32_t kBlue8    = 0x000000ff;
+#endif  // __BYTE_ORDER
+static const uint32_t kBlack32  = 0x00000000;
+static const uint32_t kWhite32  = kRed8 | kGreen8 | kBlue8;
+
+/*
+ * Extracting, and saving color bytes from / to WORD / DWORD RGB.
+ */
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+/* Extract red, green, and blue bytes from RGB565 word. */
+#define R16(rgb)    static_cast<uint8_t>(rgb & kRed5)
+#define G16(rgb)    static_cast<uint8_t>((rgb & kGreen6) >> 5)
+#define B16(rgb)    static_cast<uint8_t>((rgb & kBlue5) >> 11)
+/* Make 8 bits red, green, and blue, extracted from RGB565 word. */
+#define R16_32(rgb) static_cast<uint8_t>(((rgb & kRed5) << 3) | ((rgb & kRed5) >> 2))
+#define G16_32(rgb) static_cast<uint8_t>(((rgb & kGreen6) >> 3) | ((rgb & kGreen6) >> 9))
+#define B16_32(rgb) static_cast<uint8_t>(((rgb & kBlue5) >> 8) | ((rgb & kBlue5) >> 14))
+/* Extract red, green, and blue bytes from RGB32 dword. */
+#define R32(rgb)    static_cast<uint8_t>(rgb & kRed8)
+#define G32(rgb)    static_cast<uint8_t>(((rgb & kGreen8) >> 8) & 0xff)
+#define B32(rgb)    static_cast<uint8_t>(((rgb & kBlue8) >> 16) & 0xff)
+/* Build RGB565 word from red, green, and blue bytes. */
+#define RGB565(r, g, b) static_cast<uint16_t>((((static_cast<uint16_t>(b) << 6) | g) << 5) | r)
+/* Build RGB32 dword from red, green, and blue bytes. */
+#define RGB32(r, g, b) static_cast<uint32_t>((((static_cast<uint32_t>(b) << 8) | g) << 8) | r)
+#else   // __BYTE_ORDER
+/* Extract red, green, and blue bytes from RGB565 word. */
+#define R16(rgb)    static_cast<uint8_t>((rgb & kRed5) >> 11)
+#define G16(rgb)    static_cast<uint8_t>((rgb & kGreen6) >> 5)
+#define B16(rgb)    static_cast<uint8_t>(rgb & kBlue5)
+/* Make 8 bits red, green, and blue, extracted from RGB565 word. */
+#define R16_32(rgb) static_cast<uint8_t>(((rgb & kRed5) >> 8) | ((rgb & kRed5) >> 14))
+#define G16_32(rgb) static_cast<uint8_t>(((rgb & kGreen6) >> 3) | ((rgb & kGreen6) >> 9))
+#define B16_32(rgb) static_cast<uint8_t>(((rgb & kBlue5) << 3) | ((rgb & kBlue5) >> 2))
+/* Extract red, green, and blue bytes from RGB32 dword. */
+#define R32(rgb)    static_cast<uint8_t>((rgb & kRed8) >> 16)
+#define G32(rgb)    static_cast<uint8_t>((rgb & kGreen8) >> 8)
+#define B32(rgb)    static_cast<uint8_t>(rgb & kBlue8)
+/* Build RGB565 word from red, green, and blue bytes. */
+#define RGB565(r, g, b) static_cast<uint16_t>((((static_cast<uint16_t>(r) << 6) | g) << 5) | b)
+/* Build RGB32 dword from red, green, and blue bytes. */
+#define RGB32(r, g, b) static_cast<uint32_t>((((static_cast<uint32_t>(r) << 8) | g) << 8) | b)
+#endif  // __BYTE_ORDER
+
+/* An union that simplifies breaking 32 bit RGB into separate R, G, and B colors.
+ */
+typedef union RGB32_t {
+    uint32_t    color;
+    struct {
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+        uint8_t r; uint8_t g; uint8_t b; uint8_t a;
+#else   // __BYTE_ORDER
+        uint8_t a; uint8_t b; uint8_t g; uint8_t r;
+#endif  // __BYTE_ORDER
+    };
+} RGB32_t;
+
+
+/* Clips a value to the unsigned 0-255 range, treating negative values as zero.
+ */
+static __inline__ int
+clamp(int x)
+{
+    if (x > 255) return 255;
+    if (x < 0)   return 0;
+    return x;
+}
+
+/********************************************************************************
+ * Basics of RGB -> YUV conversion
+ *******************************************************************************/
+
+/*
+ * RGB -> YUV conversion macros
+ */
+#define RGB2Y(r, g, b) (uint8_t)(((66 * (r) + 129 * (g) +  25 * (b) + 128) >> 8) +  16)
+#define RGB2U(r, g, b) (uint8_t)(((-38 * (r) - 74 * (g) + 112 * (b) + 128) >> 8) + 128)
+#define RGB2V(r, g, b) (uint8_t)(((112 * (r) - 94 * (g) -  18 * (b) + 128) >> 8) + 128)
+
+/* Converts R8 G8 B8 color to YUV. */
+static __inline__ void
+R8G8B8ToYUV(uint8_t r, uint8_t g, uint8_t b, uint8_t* y, uint8_t* u, uint8_t* v)
+{
+    *y = RGB2Y((int)r, (int)g, (int)b);
+    *u = RGB2U((int)r, (int)g, (int)b);
+    *v = RGB2V((int)r, (int)g, (int)b);
+}
+
+/* Converts RGB565 color to YUV. */
+static __inline__ void
+RGB565ToYUV(uint16_t rgb, uint8_t* y, uint8_t* u, uint8_t* v)
+{
+    R8G8B8ToYUV(R16_32(rgb), G16_32(rgb), B16_32(rgb), y, u, v);
+}
+
+/* Converts RGB32 color to YUV. */
+static __inline__ void
+RGB32ToYUV(uint32_t rgb, uint8_t* y, uint8_t* u, uint8_t* v)
+{
+    RGB32_t rgb_c;
+    rgb_c.color = rgb;
+    R8G8B8ToYUV(rgb_c.r, rgb_c.g, rgb_c.b, y, u, v);
+}
+
+/********************************************************************************
+ * Basics of YUV -> RGB conversion.
+ * Note that due to the fact that guest uses RGB only on preview window, and the
+ * RGB format that is used is RGB565, we can limit YUV -> RGB conversions to
+ * RGB565 only.
+ *******************************************************************************/
+
+/*
+ * YUV -> RGB conversion macros
+ */
+
+/* "Optimized" macros that take specialy prepared Y, U, and V values:
+ *  C = Y - 16
+ *  D = U - 128
+ *  E = V - 128
+ */
+#define YUV2RO(C, D, E) clamp((298 * (C) + 409 * (E) + 128) >> 8)
+#define YUV2GO(C, D, E) clamp((298 * (C) - 100 * (D) - 208 * (E) + 128) >> 8)
+#define YUV2BO(C, D, E) clamp((298 * (C) + 516 * (D) + 128) >> 8)
+
+/*
+ *  Main macros that take the original Y, U, and V values
+ */
+#define YUV2R(y, u, v) clamp((298 * ((y)-16) + 409 * ((v)-128) + 128) >> 8)
+#define YUV2G(y, u, v) clamp((298 * ((y)-16) - 100 * ((u)-128) - 208 * ((v)-128) + 128) >> 8)
+#define YUV2B(y, u, v) clamp((298 * ((y)-16) + 516 * ((u)-128) + 128) >> 8)
+
+
+/* Converts YUV color to RGB565. */
+static __inline__ uint16_t
+YUVToRGB565(int y, int u, int v)
+{
+    /* Calculate C, D, and E values for the optimized macro. */
+    y -= 16; u -= 128; v -= 128;
+    const uint16_t r = (YUV2RO(y,u,v) >> 3) & 0x1f;
+    const uint16_t g = (YUV2GO(y,u,v) >> 2) & 0x3f;
+    const uint16_t b = (YUV2BO(y,u,v) >> 3) & 0x1f;
+    return RGB565(r, g, b);
+}
+
+/* Converts YUV color to RGB32. */
+static __inline__ uint32_t
+YUVToRGB32(int y, int u, int v)
+{
+    /* Calculate C, D, and E values for the optimized macro. */
+    y -= 16; u -= 128; v -= 128;
+    RGB32_t rgb;
+    rgb.r = YUV2RO(y,u,v) & 0xff;
+    rgb.g = YUV2GO(y,u,v) & 0xff;
+    rgb.b = YUV2BO(y,u,v) & 0xff;
+    return rgb.color;
+}
+
+/* YUV pixel descriptor. */
+struct YUVPixel {
+    uint8_t     Y;
+    uint8_t     U;
+    uint8_t     V;
+
+    inline YUVPixel()
+        : Y(0), U(0), V(0)
+    {
+    }
+
+    inline explicit YUVPixel(uint16_t rgb565)
+    {
+        RGB565ToYUV(rgb565, &Y, &U, &V);
+    }
+
+    inline explicit YUVPixel(uint32_t rgb32)
+    {
+        RGB32ToYUV(rgb32, &Y, &U, &V);
+    }
+
+    inline void get(uint8_t* pY, uint8_t* pU, uint8_t* pV) const
+    {
+        *pY = Y; *pU = U; *pV = V;
+    }
+};
+
+/* Converts an YV12 framebuffer to RGB565 framebuffer.
+ * Param:
+ *  yv12 - YV12 framebuffer.
+ *  rgb - RGB565 framebuffer.
+ *  width, height - Dimensions for both framebuffers.
+ */
+void YV12ToRGB565(const void* yv12, void* rgb, int width, int height);
+
+/* Converts an YV12 framebuffer to RGB32 framebuffer.
+ * Param:
+ *  yv12 - YV12 framebuffer.
+ *  rgb - RGB32 framebuffer.
+ *  width, height - Dimensions for both framebuffers.
+ */
+void YV12ToRGB32(const void* yv12, void* rgb, int width, int height);
+
+/* Converts an YU12 framebuffer to RGB32 framebuffer.
+ * Param:
+ *  yu12 - YU12 framebuffer.
+ *  rgb - RGB32 framebuffer.
+ *  width, height - Dimensions for both framebuffers.
+ */
+void YU12ToRGB32(const void* yu12, void* rgb, int width, int height);
+
+/* Converts an NV12 framebuffer to RGB565 framebuffer.
+ * Param:
+ *  nv12 - NV12 framebuffer.
+ *  rgb - RGB565 framebuffer.
+ *  width, height - Dimensions for both framebuffers.
+ */
+void NV12ToRGB565(const void* nv12, void* rgb, int width, int height);
+
+/* Converts an NV12 framebuffer to RGB32 framebuffer.
+ * Param:
+ *  nv12 - NV12 framebuffer.
+ *  rgb - RGB32 framebuffer.
+ *  width, height - Dimensions for both framebuffers.
+ */
+void NV12ToRGB32(const void* nv12, void* rgb, int width, int height);
+
+/* Converts an NV21 framebuffer to RGB565 framebuffer.
+ * Param:
+ *  nv21 - NV21 framebuffer.
+ *  rgb - RGB565 framebuffer.
+ *  width, height - Dimensions for both framebuffers.
+ */
+void NV21ToRGB565(const void* nv21, void* rgb, int width, int height);
+
+/* Converts an NV21 framebuffer to RGB32 framebuffer.
+ * Param:
+ *  nv21 - NV21 framebuffer.
+ *  rgb - RGB32 framebuffer.
+ *  width, height - Dimensions for both framebuffers.
+ */
+void NV21ToRGB32(const void* nv21, void* rgb, int width, int height);
+
+}; /* namespace android */
+
+#endif  /* HW_EMULATOR_CAMERA_CONVERTERS_H */
diff --git a/camera/EmulatedBaseCamera.cpp b/camera/EmulatedBaseCamera.cpp
new file mode 100644
index 0000000..19d398e
--- /dev/null
+++ b/camera/EmulatedBaseCamera.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 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.
+ */
+
+/*
+ * Contains implementation of a class EmulatedBaseCamera that encapsulates
+ * functionality common to all emulated camera device versions ("fake",
+ * "webcam", "video file", "cam2.0" etc.).  Instances of this class (for each
+ * emulated camera) are created during the construction of the
+ * EmulatedCameraFactory instance.  This class serves as an entry point for all
+ * camera API calls that are common across all versions of the
+ * camera_device_t/camera_module_t structures.
+ */
+
+#define LOG_NDEBUG 0
+#define LOG_TAG "EmulatedCamera_BaseCamera"
+#include <cutils/log.h>
+
+#include "EmulatedBaseCamera.h"
+
+namespace android {
+
+EmulatedBaseCamera::EmulatedBaseCamera(int cameraId,
+        uint32_t cameraVersion,
+        struct hw_device_t* device,
+        struct hw_module_t* module)
+        : mCameraInfo(NULL),
+          mCameraID(cameraId),
+          mCameraDeviceVersion(cameraVersion)
+{
+    /*
+     * Initialize camera_device descriptor for this object.
+     */
+
+    /* Common header */
+    device->tag = HARDWARE_DEVICE_TAG;
+    device->version = cameraVersion;
+    device->module = module;
+    device->close = NULL; // Must be filled in by child implementation
+}
+
+EmulatedBaseCamera::~EmulatedBaseCamera()
+{
+}
+
+status_t EmulatedBaseCamera::getCameraInfo(struct camera_info* info)
+{
+    ALOGV("%s", __FUNCTION__);
+
+    info->device_version = mCameraDeviceVersion;
+    if (mCameraDeviceVersion >= HARDWARE_DEVICE_API_VERSION(2, 0)) {
+        info->static_camera_characteristics = mCameraInfo;
+    } else {
+        info->static_camera_characteristics = (camera_metadata_t*)0xcafef00d;
+    }
+
+    return NO_ERROR;
+}
+
+
+} /* namespace android */
diff --git a/camera/EmulatedBaseCamera.h b/camera/EmulatedBaseCamera.h
new file mode 100644
index 0000000..5888ca0
--- /dev/null
+++ b/camera/EmulatedBaseCamera.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 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.
+ */
+
+#ifndef HW_EMULATOR_CAMERA_EMULATED_BASE_CAMERA_H
+#define HW_EMULATOR_CAMERA_EMULATED_BASE_CAMERA_H
+
+#include <hardware/camera_common.h>
+#include <utils/Errors.h>
+
+namespace android {
+
+/*
+ * Contains declaration of a class EmulatedBaseCamera that encapsulates
+ * functionality common to all emulated camera device versions ("fake",
+ * "webcam", "video file", etc.).  Instances of this class (for each emulated
+ * camera) are created during the construction of the EmulatedCameraFactory
+ * instance.  This class serves as an entry point for all camera API calls that
+ * are common across all versions of the camera_device_t/camera_module_t
+ * structures.
+ */
+
+class EmulatedBaseCamera {
+  public:
+    EmulatedBaseCamera(int cameraId,
+            uint32_t cameraVersion,
+            struct hw_device_t* device,
+            struct hw_module_t* module);
+
+    virtual ~EmulatedBaseCamera();
+
+    /****************************************************************************
+     * Public API
+     ***************************************************************************/
+
+  public:
+    /* Initializes EmulatedCamera instance.
+     * Return:
+     *  NO_ERROR on success, or an appropriate error status on failure.
+     */
+    virtual status_t Initialize() = 0;
+
+    /****************************************************************************
+     * Camera API implementation
+     ***************************************************************************/
+
+  public:
+    /* Creates connection to the emulated camera device.
+     * This method is called in response to hw_module_methods_t::open callback.
+     * NOTE: When this method is called the object is locked.
+     * Note that failures in this method are reported as negative EXXX statuses.
+     */
+    virtual status_t connectCamera(hw_device_t** device) = 0;
+
+    /* Closes connection to the emulated camera.
+     * This method is called in response to camera_device::close callback.
+     * NOTE: When this method is called the object is locked.
+     * Note that failures in this method are reported as negative EXXX statuses.
+     */
+    virtual status_t closeCamera() = 0;
+
+    /* Gets camera information.
+     * This method is called in response to camera_module_t::get_camera_info
+     * callback.
+     * NOTE: When this method is called the object is locked.
+     * Note that failures in this method are reported as negative EXXX statuses.
+     */
+    virtual status_t getCameraInfo(struct camera_info* info) = 0;
+
+    /****************************************************************************
+     * Data members
+     ***************************************************************************/
+
+  protected:
+    /* Fixed camera information for camera2 devices. Must be valid to access if
+     * mCameraDeviceVersion is >= HARDWARE_DEVICE_API_VERSION(2,0)  */
+    camera_metadata_t *mCameraInfo;
+
+  private:
+    /* Zero-based ID assigned to this camera. */
+    int mCameraID;
+
+    /* Version of the camera device HAL implemented by this camera */
+    int mCameraDeviceVersion;
+};
+
+} /* namespace android */
+
+#endif /* HW_EMULATOR_CAMERA_EMULATED_BASE_CAMERA_H */
diff --git a/camera/EmulatedCamera.cpp b/camera/EmulatedCamera.cpp
new file mode 100755
index 0000000..28aede1
--- /dev/null
+++ b/camera/EmulatedCamera.cpp
@@ -0,0 +1,1041 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+/*
+ * Contains implementation of a class EmulatedCamera that encapsulates
+ * functionality common to all emulated cameras ("fake", "webcam", "video file",
+ * etc.). Instances of this class (for each emulated camera) are created during
+ * the construction of the EmulatedCameraFactory instance. This class serves as
+ * an entry point for all camera API calls that defined by camera_device_ops_t
+ * API.
+ */
+
+#define LOG_NDEBUG 0
+#define LOG_TAG "EmulatedCamera_Camera"
+#include <cutils/log.h>
+#include <ui/Rect.h>
+#include "EmulatedCamera.h"
+//#include "EmulatedFakeCameraDevice.h"
+#include "Converters.h"
+
+/* Defines whether we should trace parameter changes. */
+#define DEBUG_PARAM 1
+
+namespace android {
+
+#if DEBUG_PARAM
+/* Calculates and logs parameter changes.
+ * Param:
+ *  current - Current set of camera parameters.
+ *  new_par - String representation of new parameters.
+ */
+static void PrintParamDiff(const CameraParameters& current, const char* new_par);
+#else
+#define PrintParamDiff(current, new_par)   (void(0))
+#endif  /* DEBUG_PARAM */
+
+/* A helper routine that adds a value to the camera parameter.
+ * Param:
+ *  param - Camera parameter to add a value to.
+ *  val - Value to add.
+ * Return:
+ *  A new string containing parameter with the added value on success, or NULL on
+ *  a failure. If non-NULL string is returned, the caller is responsible for
+ *  freeing it with 'free'.
+ */
+static char* AddValue(const char* param, const char* val);
+
+EmulatedCamera::EmulatedCamera(int cameraId,
+                               struct hw_module_t* module)
+        : EmulatedBaseCamera(cameraId,
+                HARDWARE_DEVICE_API_VERSION(1, 0),
+                &common,
+                module),
+          mPreviewWindow(),
+          mCallbackNotifier()
+{
+    /* camera_device v1 fields. */
+    common.close = EmulatedCamera::close;
+    ops = &mDeviceOps;
+    priv = this;
+}
+
+EmulatedCamera::~EmulatedCamera()
+{
+}
+
+/****************************************************************************
+ * Public API
+ ***************************************************************************/
+
+status_t EmulatedCamera::Initialize()
+{
+    /* Preview formats supported by this HAL. */
+    char preview_formats[1024];
+    snprintf(preview_formats, sizeof(preview_formats), "%s,%s,%s",
+             CameraParameters::PIXEL_FORMAT_YUV420SP,
+             CameraParameters::PIXEL_FORMAT_YUV420P,
+             CameraParameters::PIXEL_FORMAT_RGBA8888);
+
+    /*
+     * Fake required parameters.
+     */
+
+    mParameters.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES, "320x240,0x0");
+
+    mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, "512");
+    mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, "384");
+    mParameters.set(CameraParameters::KEY_JPEG_QUALITY, "90");
+    mParameters.set(CameraParameters::KEY_FOCAL_LENGTH, "4.31");
+    mParameters.set(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, "54.8");
+    mParameters.set(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, "42.5");
+    mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, "90");
+
+    /* Preview format settings used here are related to panoramic view only. It's
+     * not related to the preview window that works only with RGB frames, which
+     * is explicitly stated when set_buffers_geometry is called on the preview
+     * window object. */
+    mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
+                    preview_formats);
+    mParameters.setPreviewFormat(CameraParameters::PIXEL_FORMAT_YUV420SP);
+
+    /* We don't relay on the actual frame rates supported by the camera device,
+     * since we will emulate them through timeouts in the emulated camera device
+     * worker thread. */
+    mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
+                    "30,24,20,15,10,5");
+    mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE, "(5,30)");
+    mParameters.set(CameraParameters::KEY_PREVIEW_FPS_RANGE, "5,30");
+    mParameters.setPreviewFrameRate(24);
+
+    /* Only PIXEL_FORMAT_YUV420P is accepted by video framework in emulator! */
+    mParameters.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT,
+                    CameraParameters::PIXEL_FORMAT_YUV420P);
+    mParameters.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
+                    CameraParameters::PIXEL_FORMAT_JPEG);
+    mParameters.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG);
+
+    /* Set exposure compensation. */
+    mParameters.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION, "6");
+    mParameters.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION, "-6");
+    mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP, "0.5");
+    mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION, "0");
+
+    /* Sets the white balance modes and the device-dependent scale factors. */
+    char supported_white_balance[1024];
+    snprintf(supported_white_balance, sizeof(supported_white_balance),
+             "%s,%s,%s,%s",
+             CameraParameters::WHITE_BALANCE_AUTO,
+             CameraParameters::WHITE_BALANCE_INCANDESCENT,
+             CameraParameters::WHITE_BALANCE_DAYLIGHT,
+             CameraParameters::WHITE_BALANCE_TWILIGHT);
+    mParameters.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
+                    supported_white_balance);
+    mParameters.set(CameraParameters::KEY_WHITE_BALANCE,
+                    CameraParameters::WHITE_BALANCE_AUTO);
+    getCameraDevice()->initializeWhiteBalanceModes(
+            CameraParameters::WHITE_BALANCE_AUTO, 1.0f, 1.0f);
+    getCameraDevice()->initializeWhiteBalanceModes(
+            CameraParameters::WHITE_BALANCE_INCANDESCENT, 1.38f, 0.60f);
+    getCameraDevice()->initializeWhiteBalanceModes(
+            CameraParameters::WHITE_BALANCE_DAYLIGHT, 1.09f, 0.92f);
+    getCameraDevice()->initializeWhiteBalanceModes(
+            CameraParameters::WHITE_BALANCE_TWILIGHT, 0.92f, 1.22f);
+    getCameraDevice()->setWhiteBalanceMode(CameraParameters::WHITE_BALANCE_AUTO);
+
+    /* Not supported features
+     */
+    mParameters.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
+                    CameraParameters::FOCUS_MODE_FIXED);
+    mParameters.set(CameraParameters::KEY_FOCUS_MODE,
+                    CameraParameters::FOCUS_MODE_FIXED);
+
+    return NO_ERROR;
+}
+
+void EmulatedCamera::onNextFrameAvailable(const void* frame,
+                                          nsecs_t timestamp,
+                                          EmulatedCameraDevice* camera_dev)
+{
+    /* Notify the preview window first. */
+    mPreviewWindow.onNextFrameAvailable(frame, timestamp, camera_dev);
+
+    /* Notify callback notifier next. */
+    mCallbackNotifier.onNextFrameAvailable(frame, timestamp, camera_dev);
+}
+
+void EmulatedCamera::onCameraDeviceError(int err)
+{
+    /* Errors are reported through the callback notifier */
+    mCallbackNotifier.onCameraDeviceError(err);
+}
+
+/****************************************************************************
+ * Camera API implementation.
+ ***************************************************************************/
+
+status_t EmulatedCamera::connectCamera(hw_device_t** device)
+{
+    ALOGV("%s", __FUNCTION__);
+
+    status_t res = EINVAL;
+    EmulatedCameraDevice* const camera_dev = getCameraDevice();
+    ALOGE_IF(camera_dev == NULL, "%s: No camera device instance.", __FUNCTION__);
+
+    if (camera_dev != NULL) {
+        /* Connect to the camera device. */
+        res = getCameraDevice()->connectDevice();
+        if (res == NO_ERROR) {
+            *device = &common;
+        }
+    }
+
+    return -res;
+}
+
+status_t EmulatedCamera::closeCamera()
+{
+    ALOGV("%s", __FUNCTION__);
+
+    return cleanupCamera();
+}
+
+status_t EmulatedCamera::getCameraInfo(struct camera_info* info)
+{
+    ALOGV("%s", __FUNCTION__);
+
+    const char* valstr = NULL;
+
+    valstr = mParameters.get(EmulatedCamera::FACING_KEY);
+    if (valstr != NULL) {
+        if (strcmp(valstr, EmulatedCamera::FACING_FRONT) == 0) {
+            info->facing = CAMERA_FACING_FRONT;
+        }
+        else if (strcmp(valstr, EmulatedCamera::FACING_BACK) == 0) {
+            info->facing = CAMERA_FACING_BACK;
+        }
+    } else {
+        info->facing = CAMERA_FACING_BACK;
+    }
+
+    valstr = mParameters.get(EmulatedCamera::ORIENTATION_KEY);
+    if (valstr != NULL) {
+        info->orientation = atoi(valstr);
+    } else {
+        info->orientation = 0;
+    }
+
+    return EmulatedBaseCamera::getCameraInfo(info);
+}
+
+status_t EmulatedCamera::setPreviewWindow(struct preview_stream_ops* window)
+{
+    /* Callback should return a negative errno. */
+    return -mPreviewWindow.setPreviewWindow(window,
+                                             mParameters.getPreviewFrameRate());
+}
+
+void EmulatedCamera::setCallbacks(camera_notify_callback notify_cb,
+                                  camera_data_callback data_cb,
+                                  camera_data_timestamp_callback data_cb_timestamp,
+                                  camera_request_memory get_memory,
+                                  void* user)
+{
+    mCallbackNotifier.setCallbacks(notify_cb, data_cb, data_cb_timestamp,
+                                    get_memory, user);
+}
+
+void EmulatedCamera::enableMsgType(int32_t msg_type)
+{
+    mCallbackNotifier.enableMessage(msg_type);
+}
+
+void EmulatedCamera::disableMsgType(int32_t msg_type)
+{
+    mCallbackNotifier.disableMessage(msg_type);
+}
+
+int EmulatedCamera::isMsgTypeEnabled(int32_t msg_type)
+{
+    return mCallbackNotifier.isMessageEnabled(msg_type);
+}
+
+status_t EmulatedCamera::startPreview()
+{
+    /* Callback should return a negative errno. */
+    return -doStartPreview();
+}
+
+void EmulatedCamera::stopPreview()
+{
+    doStopPreview();
+}
+
+int EmulatedCamera::isPreviewEnabled()
+{
+    return mPreviewWindow.isPreviewEnabled();
+}
+
+status_t EmulatedCamera::storeMetaDataInBuffers(int enable)
+{
+    /* Callback should return a negative errno. */
+    return -mCallbackNotifier.storeMetaDataInBuffers(enable);
+}
+
+status_t EmulatedCamera::startRecording()
+{
+    /* Callback should return a negative errno. */
+    return -mCallbackNotifier.enableVideoRecording(mParameters.getPreviewFrameRate());
+}
+
+void EmulatedCamera::stopRecording()
+{
+    mCallbackNotifier.disableVideoRecording();
+}
+
+int EmulatedCamera::isRecordingEnabled()
+{
+    return mCallbackNotifier.isVideoRecordingEnabled();
+}
+
+void EmulatedCamera::releaseRecordingFrame(const void* opaque)
+{
+    mCallbackNotifier.releaseRecordingFrame(opaque);
+}
+
+status_t EmulatedCamera::setAutoFocus()
+{
+    ALOGV("%s", __FUNCTION__);
+
+    /* TODO: Future enhancements. */
+    return NO_ERROR;
+}
+
+status_t EmulatedCamera::cancelAutoFocus()
+{
+    ALOGV("%s", __FUNCTION__);
+
+    /* TODO: Future enhancements. */
+    return NO_ERROR;
+}
+
+status_t EmulatedCamera::takePicture()
+{
+    ALOGV("%s", __FUNCTION__);
+
+    status_t res;
+    int width, height;
+    uint32_t org_fmt;
+
+    /* Collect frame info for the picture. */
+    mParameters.getPictureSize(&width, &height);
+    const char* pix_fmt = mParameters.getPictureFormat();
+    if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_YUV420P) == 0) {
+        org_fmt = V4L2_PIX_FMT_YUV420;
+    } else if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_RGBA8888) == 0) {
+        org_fmt = V4L2_PIX_FMT_RGB32;
+    } else if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) {
+        org_fmt = V4L2_PIX_FMT_NV21;
+    } else if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_JPEG) == 0) {
+        /* We only have JPEG converted for NV21 format. */
+        org_fmt = V4L2_PIX_FMT_NV21;
+    } else {
+        ALOGE("%s: Unsupported pixel format %s", __FUNCTION__, pix_fmt);
+        return EINVAL;
+    }
+    /* Get JPEG quality. */
+    int jpeg_quality = mParameters.getInt(CameraParameters::KEY_JPEG_QUALITY);
+    if (jpeg_quality <= 0) {
+        jpeg_quality = 90;  /* Fall back to default. */
+    }
+
+    /*
+     * Make sure preview is not running, and device is stopped before taking
+     * picture.
+     */
+
+    const bool preview_on = mPreviewWindow.isPreviewEnabled();
+    if (preview_on) {
+        doStopPreview();
+    }
+
+    /* Camera device should have been stopped when the shutter message has been
+     * enabled. */
+    EmulatedCameraDevice* const camera_dev = getCameraDevice();
+    if (camera_dev->isStarted()) {
+        ALOGW("%s: Camera device is started", __FUNCTION__);
+        camera_dev->stopDeliveringFrames();
+        camera_dev->stopDevice();
+    }
+
+    /*
+     * Take the picture now.
+     */
+
+    /* Start camera device for the picture frame. */
+    ALOGD("Starting camera for picture: %.4s(%s)[%dx%d]",
+         reinterpret_cast<const char*>(&org_fmt), pix_fmt, width, height);
+    res = camera_dev->startDevice(width, height, org_fmt);
+    if (res != NO_ERROR) {
+        if (preview_on) {
+            doStartPreview();
+        }
+        return res;
+    }
+
+    /* Deliver one frame only. */
+    mCallbackNotifier.setJpegQuality(jpeg_quality);
+    mCallbackNotifier.setTakingPicture(true);
+    res = camera_dev->startDeliveringFrames(true);
+    if (res != NO_ERROR) {
+        mCallbackNotifier.setTakingPicture(false);
+        if (preview_on) {
+            doStartPreview();
+        }
+    }
+    return res;
+}
+
+status_t EmulatedCamera::cancelPicture()
+{
+    ALOGV("%s", __FUNCTION__);
+
+    return NO_ERROR;
+}
+
+status_t EmulatedCamera::setParameters(const char* parms)
+{
+    ALOGV("%s", __FUNCTION__);
+    PrintParamDiff(mParameters, parms);
+
+    CameraParameters new_param;
+    String8 str8_param(parms);
+    new_param.unflatten(str8_param);
+
+    /*
+     * Check for new exposure compensation parameter.
+     */
+    int new_exposure_compensation = new_param.getInt(
+            CameraParameters::KEY_EXPOSURE_COMPENSATION);
+    const int min_exposure_compensation = new_param.getInt(
+            CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION);
+    const int max_exposure_compensation = new_param.getInt(
+            CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION);
+
+    // Checks if the exposure compensation change is supported.
+    if ((min_exposure_compensation != 0) || (max_exposure_compensation != 0)) {
+        if (new_exposure_compensation > max_exposure_compensation) {
+            new_exposure_compensation = max_exposure_compensation;
+        }
+        if (new_exposure_compensation < min_exposure_compensation) {
+            new_exposure_compensation = min_exposure_compensation;
+        }
+
+        const int current_exposure_compensation = mParameters.getInt(
+                CameraParameters::KEY_EXPOSURE_COMPENSATION);
+        if (current_exposure_compensation != new_exposure_compensation) {
+            const float exposure_value = new_exposure_compensation *
+                    new_param.getFloat(
+                            CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP);
+
+            getCameraDevice()->setExposureCompensation(
+                    exposure_value);
+        }
+    }
+
+    const char* new_white_balance = new_param.get(
+            CameraParameters::KEY_WHITE_BALANCE);
+    const char* supported_white_balance = new_param.get(
+            CameraParameters::KEY_SUPPORTED_WHITE_BALANCE);
+
+    if ((supported_white_balance != NULL) && (new_white_balance != NULL) &&
+        (strstr(supported_white_balance, new_white_balance) != NULL)) {
+
+        const char* current_white_balance = mParameters.get(
+                CameraParameters::KEY_WHITE_BALANCE);
+        if ((current_white_balance == NULL) ||
+            (strcmp(current_white_balance, new_white_balance) != 0)) {
+            ALOGV("Setting white balance to %s", new_white_balance);
+            getCameraDevice()->setWhiteBalanceMode(new_white_balance);
+        }
+    }
+
+    mParameters = new_param;
+
+    return NO_ERROR;
+}
+
+/* A dumb variable indicating "no params" / error on the exit from
+ * EmulatedCamera::getParameters(). */
+static char lNoParam = '\0';
+char* EmulatedCamera::getParameters()
+{
+    String8 params(mParameters.flatten());
+    char* ret_str =
+        reinterpret_cast<char*>(malloc(sizeof(char) * (params.length()+1)));
+    memset(ret_str, 0, params.length()+1);
+    if (ret_str != NULL) {
+        strncpy(ret_str, params.string(), params.length()+1);
+        return ret_str;
+    } else {
+        ALOGE("%s: Unable to allocate string for %s", __FUNCTION__, params.string());
+        /* Apparently, we can't return NULL fron this routine. */
+        return &lNoParam;
+    }
+}
+
+void EmulatedCamera::putParameters(char* params)
+{
+    /* This method simply frees parameters allocated in getParameters(). */
+    if (params != NULL && params != &lNoParam) {
+        free(params);
+    }
+}
+
+status_t EmulatedCamera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
+{
+    ALOGV("%s: cmd = %d, arg1 = %d, arg2 = %d", __FUNCTION__, cmd, arg1, arg2);
+
+    /* TODO: Future enhancements. */
+    return 0;
+}
+
+void EmulatedCamera::releaseCamera()
+{
+    ALOGV("%s", __FUNCTION__);
+
+    cleanupCamera();
+}
+
+status_t EmulatedCamera::dumpCamera(int fd)
+{
+    ALOGV("%s", __FUNCTION__);
+
+    /* TODO: Future enhancements. */
+    return -EINVAL;
+}
+
+/****************************************************************************
+ * Preview management.
+ ***************************************************************************/
+
+status_t EmulatedCamera::doStartPreview()
+{
+    ALOGV("%s", __FUNCTION__);
+
+    EmulatedCameraDevice* camera_dev = getCameraDevice();
+    if (camera_dev->isStarted()) {
+        camera_dev->stopDeliveringFrames();
+        camera_dev->stopDevice();
+    }
+
+    status_t res = mPreviewWindow.startPreview();
+    if (res != NO_ERROR) {
+        return res;
+    }
+
+    /* Make sure camera device is connected. */
+    if (!camera_dev->isConnected()) {
+        res = camera_dev->connectDevice();
+        if (res != NO_ERROR) {
+            mPreviewWindow.stopPreview();
+            return res;
+        }
+    }
+
+    int width, height;
+    /* Lets see what should we use for frame width, and height. */
+    if (mParameters.get(CameraParameters::KEY_VIDEO_SIZE) != NULL) {
+        mParameters.getVideoSize(&width, &height);
+    } else {
+        mParameters.getPreviewSize(&width, &height);
+    }
+    /* Lets see what should we use for the frame pixel format. Note that there
+     * are two parameters that define pixel formats for frames sent to the
+     * application via notification callbacks:
+     * - KEY_VIDEO_FRAME_FORMAT, that is used when recording video, and
+     * - KEY_PREVIEW_FORMAT, that is used for preview frame notification.
+     * We choose one or the other, depending on "recording-hint" property set by
+     * the framework that indicating intention: video, or preview. */
+    const char* pix_fmt = NULL;
+    const char* is_video = mParameters.get(EmulatedCamera::RECORDING_HINT_KEY);
+    if (is_video == NULL) {
+        is_video = CameraParameters::FALSE;
+    }
+    if (strcmp(is_video, CameraParameters::TRUE) == 0) {
+        /* Video recording is requested. Lets see if video frame format is set. */
+        pix_fmt = mParameters.get(CameraParameters::KEY_VIDEO_FRAME_FORMAT);
+    }
+    /* If this was not video recording, or video frame format is not set, lets
+     * use preview pixel format for the main framebuffer. */
+    if (pix_fmt == NULL) {
+        pix_fmt = mParameters.getPreviewFormat();
+    }
+    if (pix_fmt == NULL) {
+        ALOGE("%s: Unable to obtain video format", __FUNCTION__);
+        mPreviewWindow.stopPreview();
+        return EINVAL;
+    }
+
+    /* Convert framework's pixel format to the FOURCC one. */
+    uint32_t org_fmt;
+    if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_YUV420P) == 0) {
+        org_fmt = V4L2_PIX_FMT_YUV420;
+    } else if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_RGBA8888) == 0) {
+        org_fmt = V4L2_PIX_FMT_RGB32;
+    } else if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) {
+        org_fmt = V4L2_PIX_FMT_NV21;
+    } else {
+        ALOGE("%s: Unsupported pixel format %s", __FUNCTION__, pix_fmt);
+        mPreviewWindow.stopPreview();
+        return EINVAL;
+    }
+    ALOGD("Starting camera: %dx%d -> %.4s(%s)",
+         width, height, reinterpret_cast<const char*>(&org_fmt), pix_fmt);
+    res = camera_dev->startDevice(width, height, org_fmt);
+    if (res != NO_ERROR) {
+        mPreviewWindow.stopPreview();
+        return res;
+    }
+
+    res = camera_dev->startDeliveringFrames(false);
+    if (res != NO_ERROR) {
+        camera_dev->stopDevice();
+        mPreviewWindow.stopPreview();
+    }
+
+    return res;
+}
+
+status_t EmulatedCamera::doStopPreview()
+{
+    ALOGV("%s", __FUNCTION__);
+
+    status_t res = NO_ERROR;
+    if (mPreviewWindow.isPreviewEnabled()) {
+        /* Stop the camera. */
+        if (getCameraDevice()->isStarted()) {
+            getCameraDevice()->stopDeliveringFrames();
+            res = getCameraDevice()->stopDevice();
+        }
+
+        if (res == NO_ERROR) {
+            /* Disable preview as well. */
+            mPreviewWindow.stopPreview();
+        }
+    }
+
+    return NO_ERROR;
+}
+
+/****************************************************************************
+ * Private API.
+ ***************************************************************************/
+
+status_t EmulatedCamera::cleanupCamera()
+{
+    status_t res = NO_ERROR;
+
+    /* If preview is running - stop it. */
+    res = doStopPreview();
+    if (res != NO_ERROR) {
+        return -res;
+    }
+
+    /* Stop and disconnect the camera device. */
+    EmulatedCameraDevice* const camera_dev = getCameraDevice();
+    if (camera_dev != NULL) {
+        if (camera_dev->isStarted()) {
+            camera_dev->stopDeliveringFrames();
+            res = camera_dev->stopDevice();
+            if (res != NO_ERROR) {
+                return -res;
+            }
+        }
+        if (camera_dev->isConnected()) {
+            res = camera_dev->disconnectDevice();
+            if (res != NO_ERROR) {
+                return -res;
+            }
+        }
+    }
+
+    mCallbackNotifier.cleanupCBNotifier();
+
+    return NO_ERROR;
+}
+
+/****************************************************************************
+ * Camera API callbacks as defined by camera_device_ops structure.
+ *
+ * Callbacks here simply dispatch the calls to an appropriate method inside
+ * EmulatedCamera instance, defined by the 'dev' parameter.
+ ***************************************************************************/
+
+int EmulatedCamera::set_preview_window(struct camera_device* dev,
+                                       struct preview_stream_ops* window)
+{
+    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
+    if (ec == NULL) {
+        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
+        return -EINVAL;
+    }
+    return ec->setPreviewWindow(window);
+}
+
+void EmulatedCamera::set_callbacks(
+        struct camera_device* dev,
+        camera_notify_callback notify_cb,
+        camera_data_callback data_cb,
+        camera_data_timestamp_callback data_cb_timestamp,
+        camera_request_memory get_memory,
+        void* user)
+{
+    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
+    if (ec == NULL) {
+        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
+        return;
+    }
+    ec->setCallbacks(notify_cb, data_cb, data_cb_timestamp, get_memory, user);
+}
+
+void EmulatedCamera::enable_msg_type(struct camera_device* dev, int32_t msg_type)
+{
+    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
+    if (ec == NULL) {
+        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
+        return;
+    }
+    ec->enableMsgType(msg_type);
+}
+
+void EmulatedCamera::disable_msg_type(struct camera_device* dev, int32_t msg_type)
+{
+    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
+    if (ec == NULL) {
+        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
+        return;
+    }
+    ec->disableMsgType(msg_type);
+}
+
+int EmulatedCamera::msg_type_enabled(struct camera_device* dev, int32_t msg_type)
+{
+    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
+    if (ec == NULL) {
+        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
+        return -EINVAL;
+    }
+    return ec->isMsgTypeEnabled(msg_type);
+}
+
+int EmulatedCamera::start_preview(struct camera_device* dev)
+{
+    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
+    if (ec == NULL) {
+        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
+        return -EINVAL;
+    }
+    return ec->startPreview();
+}
+
+void EmulatedCamera::stop_preview(struct camera_device* dev)
+{
+    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
+    if (ec == NULL) {
+        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
+        return;
+    }
+    ec->stopPreview();
+}
+
+int EmulatedCamera::preview_enabled(struct camera_device* dev)
+{
+    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
+    if (ec == NULL) {
+        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
+        return -EINVAL;
+    }
+    return ec->isPreviewEnabled();
+}
+
+int EmulatedCamera::store_meta_data_in_buffers(struct camera_device* dev,
+                                               int enable)
+{
+    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
+    if (ec == NULL) {
+        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
+        return -EINVAL;
+    }
+    return ec->storeMetaDataInBuffers(enable);
+}
+
+int EmulatedCamera::start_recording(struct camera_device* dev)
+{
+    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
+    if (ec == NULL) {
+        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
+        return -EINVAL;
+    }
+    return ec->startRecording();
+}
+
+void EmulatedCamera::stop_recording(struct camera_device* dev)
+{
+    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
+    if (ec == NULL) {
+        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
+        return;
+    }
+    ec->stopRecording();
+}
+
+int EmulatedCamera::recording_enabled(struct camera_device* dev)
+{
+    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
+    if (ec == NULL) {
+        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
+        return -EINVAL;
+    }
+    return ec->isRecordingEnabled();
+}
+
+void EmulatedCamera::release_recording_frame(struct camera_device* dev,
+                                             const void* opaque)
+{
+    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
+    if (ec == NULL) {
+        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
+        return;
+    }
+    ec->releaseRecordingFrame(opaque);
+}
+
+int EmulatedCamera::auto_focus(struct camera_device* dev)
+{
+    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
+    if (ec == NULL) {
+        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
+        return -EINVAL;
+    }
+    return ec->setAutoFocus();
+}
+
+int EmulatedCamera::cancel_auto_focus(struct camera_device* dev)
+{
+    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
+    if (ec == NULL) {
+        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
+        return -EINVAL;
+    }
+    return ec->cancelAutoFocus();
+}
+
+int EmulatedCamera::take_picture(struct camera_device* dev)
+{
+    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
+    if (ec == NULL) {
+        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
+        return -EINVAL;
+    }
+    return ec->takePicture();
+}
+
+int EmulatedCamera::cancel_picture(struct camera_device* dev)
+{
+    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
+    if (ec == NULL) {
+        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
+        return -EINVAL;
+    }
+    return ec->cancelPicture();
+}
+
+int EmulatedCamera::set_parameters(struct camera_device* dev, const char* parms)
+{
+    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
+    if (ec == NULL) {
+        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
+        return -EINVAL;
+    }
+    return ec->setParameters(parms);
+}
+
+char* EmulatedCamera::get_parameters(struct camera_device* dev)
+{
+    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
+    if (ec == NULL) {
+        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
+        return NULL;
+    }
+    return ec->getParameters();
+}
+
+void EmulatedCamera::put_parameters(struct camera_device* dev, char* params)
+{
+    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
+    if (ec == NULL) {
+        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
+        return;
+    }
+    ec->putParameters(params);
+}
+
+int EmulatedCamera::send_command(struct camera_device* dev,
+                                 int32_t cmd,
+                                 int32_t arg1,
+                                 int32_t arg2)
+{
+    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
+    if (ec == NULL) {
+        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
+        return -EINVAL;
+    }
+    return ec->sendCommand(cmd, arg1, arg2);
+}
+
+void EmulatedCamera::release(struct camera_device* dev)
+{
+    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
+    if (ec == NULL) {
+        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
+        return;
+    }
+    ec->releaseCamera();
+}
+
+int EmulatedCamera::dump(struct camera_device* dev, int fd)
+{
+    EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
+    if (ec == NULL) {
+        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
+        return -EINVAL;
+    }
+    return ec->dumpCamera(fd);
+}
+
+int EmulatedCamera::close(struct hw_device_t* device)
+{
+    EmulatedCamera* ec =
+        reinterpret_cast<EmulatedCamera*>(reinterpret_cast<struct camera_device*>(device)->priv);
+    if (ec == NULL) {
+        ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
+        return -EINVAL;
+    }
+    return ec->closeCamera();
+}
+
+/****************************************************************************
+ * Static initializer for the camera callback API
+ ****************************************************************************/
+
+camera_device_ops_t EmulatedCamera::mDeviceOps = {
+    EmulatedCamera::set_preview_window,
+    EmulatedCamera::set_callbacks,
+    EmulatedCamera::enable_msg_type,
+    EmulatedCamera::disable_msg_type,
+    EmulatedCamera::msg_type_enabled,
+    EmulatedCamera::start_preview,
+    EmulatedCamera::stop_preview,
+    EmulatedCamera::preview_enabled,
+    EmulatedCamera::store_meta_data_in_buffers,
+    EmulatedCamera::start_recording,
+    EmulatedCamera::stop_recording,
+    EmulatedCamera::recording_enabled,
+    EmulatedCamera::release_recording_frame,
+    EmulatedCamera::auto_focus,
+    EmulatedCamera::cancel_auto_focus,
+    EmulatedCamera::take_picture,
+    EmulatedCamera::cancel_picture,
+    EmulatedCamera::set_parameters,
+    EmulatedCamera::get_parameters,
+    EmulatedCamera::put_parameters,
+    EmulatedCamera::send_command,
+    EmulatedCamera::release,
+    EmulatedCamera::dump
+};
+
+/****************************************************************************
+ * Common keys
+ ***************************************************************************/
+
+const char EmulatedCamera::FACING_KEY[]         = "prop-facing";
+const char EmulatedCamera::ORIENTATION_KEY[]    = "prop-orientation";
+const char EmulatedCamera::RECORDING_HINT_KEY[] = "recording-hint";
+
+/****************************************************************************
+ * Common string values
+ ***************************************************************************/
+
+const char EmulatedCamera::FACING_BACK[]      = "back";
+const char EmulatedCamera::FACING_FRONT[]     = "front";
+
+/****************************************************************************
+ * Helper routines
+ ***************************************************************************/
+
+static char* AddValue(const char* param, const char* val)
+{
+    const size_t len1 = strlen(param);
+    const size_t len2 = strlen(val);
+    char* ret = reinterpret_cast<char*>(malloc(len1 + len2 + 2));
+    ALOGE_IF(ret == NULL, "%s: Memory failure", __FUNCTION__);
+    if (ret != NULL) {
+        memcpy(ret, param, len1);
+        ret[len1] = ',';
+        memcpy(ret + len1 + 1, val, len2);
+        ret[len1 + len2 + 1] = '\0';
+    }
+    return ret;
+}
+
+/****************************************************************************
+ * Parameter debugging helpers
+ ***************************************************************************/
+
+#if DEBUG_PARAM
+static void PrintParamDiff(const CameraParameters& current,
+                            const char* new_par)
+{
+    char tmp[2048];
+    const char* wrk = new_par;
+
+    /* Divided with ';' */
+    const char* next = strchr(wrk, ';');
+    while (next != NULL) {
+        snprintf(tmp, sizeof(tmp), "%.*s", next-wrk, wrk);
+        /* in the form key=value */
+        char* val = strchr(tmp, '=');
+        if (val != NULL) {
+            *val = '\0'; val++;
+            const char* in_current = current.get(tmp);
+            if (in_current != NULL) {
+                if (strcmp(in_current, val)) {
+                    ALOGD("=== Value changed: %s: %s -> %s", tmp, in_current, val);
+                }
+            } else {
+                ALOGD("+++ New parameter: %s=%s", tmp, val);
+            }
+        } else {
+            ALOGW("No value separator in %s", tmp);
+        }
+        wrk = next + 1;
+        next = strchr(wrk, ';');
+    }
+}
+#endif  /* DEBUG_PARAM */
+
+}; /* namespace android */
diff --git a/camera/EmulatedCamera.h b/camera/EmulatedCamera.h
new file mode 100755
index 0000000..9825d5d
--- /dev/null
+++ b/camera/EmulatedCamera.h
@@ -0,0 +1,401 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef HW_EMULATOR_CAMERA_EMULATED_CAMERA_H
+#define HW_EMULATOR_CAMERA_EMULATED_CAMERA_H
+
+/*
+ * Contains declaration of a class EmulatedCamera that encapsulates
+ * functionality common to all version 1.0 emulated camera devices ("fake",
+ * "webcam", "video file", etc.).  Instances of this class (for each emulated
+ * camera) are created during the construction of the EmulatedCameraFactory
+ * instance.  This class serves as an entry point for all camera API calls that
+ * defined by camera_device_ops_t API.
+ */
+
+#include <camera/CameraParameters.h>
+#include "EmulatedBaseCamera.h"
+#include "EmulatedCameraDevice.h"
+#include "PreviewWindow.h"
+#include "CallbackNotifier.h"
+
+namespace android {
+
+/* Encapsulates functionality common to all version 1.0 emulated camera devices
+ * ("fake", "webcam", "file stream", etc.).
+ *
+ * Note that EmulatedCameraFactory instantiates object of this class just once,
+ * when EmulatedCameraFactory instance gets constructed. Connection to /
+ * disconnection from the actual camera device is handled by calls to
+ * connectDevice(), and closeCamera() methods of this class that are ivoked in
+ * response to hw_module_methods_t::open, and camera_device::close callbacks.
+ */
+class EmulatedCamera : public camera_device, public EmulatedBaseCamera {
+public:
+    /* Constructs EmulatedCamera instance.
+     * Param:
+     *  cameraId - Zero based camera identifier, which is an index of the camera
+     *      instance in camera factory's array.
+     *  module - Emulated camera HAL module descriptor.
+     */
+    EmulatedCamera(int cameraId,
+                   struct hw_module_t* module);
+
+    /* Destructs EmulatedCamera instance. */
+    virtual ~EmulatedCamera();
+
+    /****************************************************************************
+     * Abstract API
+     ***************************************************************************/
+
+public:
+    /* Gets emulated camera device used by this instance of the emulated camera.
+     */
+    virtual EmulatedCameraDevice* getCameraDevice() = 0;
+
+    /****************************************************************************
+     * Public API
+     ***************************************************************************/
+
+public:
+    /** Override of base class method */
+    virtual status_t Initialize();
+
+    /* Next frame is available in the camera device.
+     * This is a notification callback that is invoked by the camera device when
+     * a new frame is available.
+     * Note that most likely this method is called in context of a worker thread
+     * that camera device has created for frame capturing.
+     * Param:
+     *  frame - Captured frame, or NULL if camera device didn't pull the frame
+     *      yet. If NULL is passed in this parameter use GetCurrentFrame method
+     *      of the camera device class to obtain the next frame. Also note that
+     *      the size of the frame that is passed here (as well as the frame
+     *      returned from the GetCurrentFrame method) is defined by the current
+     *      frame settings (width + height + pixel format) for the camera device.
+     * timestamp - Frame's timestamp.
+     * camera_dev - Camera device instance that delivered the frame.
+     */
+    virtual void onNextFrameAvailable(const void* frame,
+                                      nsecs_t timestamp,
+                                      EmulatedCameraDevice* camera_dev);
+
+    /* Entry point for notifications that occur in camera device.
+     * Param:
+     *  err - CAMERA_ERROR_XXX error code.
+     */
+    virtual void onCameraDeviceError(int err);
+
+    /****************************************************************************
+     * Camera API implementation
+     ***************************************************************************/
+
+public:
+    /** Override of base class method */
+    virtual status_t connectCamera(hw_device_t** device);
+
+    /** Override of base class method */
+    virtual status_t closeCamera();
+
+    /** Override of base class method */
+    virtual status_t getCameraInfo(struct camera_info* info);
+
+    /****************************************************************************
+     * Camera API implementation.
+     * These methods are called from the camera API callback routines.
+     ***************************************************************************/
+
+protected:
+    /* Actual handler for camera_device_ops_t::set_preview_window callback.
+     * NOTE: When this method is called the object is locked.
+     * Note that failures in this method are reported as negave EXXX statuses.
+     */
+    virtual status_t setPreviewWindow(struct preview_stream_ops *window);
+
+    /* Actual handler for camera_device_ops_t::set_callbacks callback.
+     * NOTE: When this method is called the object is locked.
+     */
+    virtual void setCallbacks(camera_notify_callback notify_cb,
+                              camera_data_callback data_cb,
+                              camera_data_timestamp_callback data_cb_timestamp,
+                              camera_request_memory get_memory,
+                              void* user);
+
+    /* Actual handler for camera_device_ops_t::enable_msg_type callback.
+     * NOTE: When this method is called the object is locked.
+     */
+    virtual void enableMsgType(int32_t msg_type);
+
+    /* Actual handler for camera_device_ops_t::disable_msg_type callback.
+     * NOTE: When this method is called the object is locked.
+     */
+    virtual void disableMsgType(int32_t msg_type);
+
+    /* Actual handler for camera_device_ops_t::msg_type_enabled callback.
+     * NOTE: When this method is called the object is locked.
+     * Return:
+     *  0 if message(s) is (are) disabled, != 0 if enabled.
+     */
+    virtual int isMsgTypeEnabled(int32_t msg_type);
+
+    /* Actual handler for camera_device_ops_t::start_preview callback.
+     * NOTE: When this method is called the object is locked.
+     * Note that failures in this method are reported as negave EXXX statuses.
+     */
+    virtual status_t startPreview();
+
+    /* Actual handler for camera_device_ops_t::stop_preview callback.
+     * NOTE: When this method is called the object is locked.
+     */
+    virtual void stopPreview();
+
+    /* Actual handler for camera_device_ops_t::preview_enabled callback.
+     * NOTE: When this method is called the object is locked.
+     * Return:
+     *  0 if preview is disabled, != 0 if enabled.
+     */
+    virtual int isPreviewEnabled();
+
+    /* Actual handler for camera_device_ops_t::store_meta_data_in_buffers callback.
+     * NOTE: When this method is called the object is locked.
+     * Note that failures in this method are reported as negave EXXX statuses.
+     */
+    virtual status_t storeMetaDataInBuffers(int enable);
+
+    /* Actual handler for camera_device_ops_t::start_recording callback.
+     * NOTE: When this method is called the object is locked.
+     * Note that failures in this method are reported as negave EXXX statuses.
+     */
+    virtual status_t startRecording();
+
+    /* Actual handler for camera_device_ops_t::stop_recording callback.
+     * NOTE: When this method is called the object is locked.
+     */
+    virtual void stopRecording();
+
+    /* Actual handler for camera_device_ops_t::recording_enabled callback.
+     * NOTE: When this method is called the object is locked.
+     * Return:
+     *  0 if recording is disabled, != 0 if enabled.
+     */
+    virtual int isRecordingEnabled();
+
+    /* Actual handler for camera_device_ops_t::release_recording_frame callback.
+     * NOTE: When this method is called the object is locked.
+     */
+    virtual void releaseRecordingFrame(const void* opaque);
+
+    /* Actual handler for camera_device_ops_t::auto_focus callback.
+     * NOTE: When this method is called the object is locked.
+     * Note that failures in this method are reported as negave EXXX statuses.
+     */
+    virtual status_t setAutoFocus();
+
+    /* Actual handler for camera_device_ops_t::cancel_auto_focus callback.
+     * NOTE: When this method is called the object is locked.
+     * Note that failures in this method are reported as negave EXXX statuses.
+     */
+    virtual status_t cancelAutoFocus();
+
+    /* Actual handler for camera_device_ops_t::take_picture callback.
+     * NOTE: When this method is called the object is locked.
+     * Note that failures in this method are reported as negave EXXX statuses.
+     */
+    virtual status_t takePicture();
+
+    /* Actual handler for camera_device_ops_t::cancel_picture callback.
+     * NOTE: When this method is called the object is locked.
+     * Note that failures in this method are reported as negave EXXX statuses.
+     */
+    virtual status_t cancelPicture();
+
+    /* Actual handler for camera_device_ops_t::set_parameters callback.
+     * NOTE: When this method is called the object is locked.
+     * Note that failures in this method are reported as negave EXXX statuses.
+     */
+    virtual status_t setParameters(const char* parms);
+
+    /* Actual handler for camera_device_ops_t::get_parameters callback.
+     * NOTE: When this method is called the object is locked.
+     * Return:
+     *  Flattened parameters string. The caller will free the buffer allocated
+     *  for the string by calling camera_device_ops_t::put_parameters callback.
+     */
+    virtual char* getParameters();
+
+    /* Actual handler for camera_device_ops_t::put_parameters callback.
+     * Called to free the string returned from camera_device_ops_t::get_parameters
+     * callback. There is nothing more to it: the name of the callback is just
+     * misleading.
+     * NOTE: When this method is called the object is locked.
+     */
+    virtual void putParameters(char* params);
+
+    /* Actual handler for camera_device_ops_t::send_command callback.
+     * NOTE: When this method is called the object is locked.
+     * Note that failures in this method are reported as negave EXXX statuses.
+     */
+    virtual status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2);
+
+    /* Actual handler for camera_device_ops_t::release callback.
+     * NOTE: When this method is called the object is locked.
+     */
+    virtual void releaseCamera();
+
+    /* Actual handler for camera_device_ops_t::dump callback.
+     * NOTE: When this method is called the object is locked.
+     * Note that failures in this method are reported as negave EXXX statuses.
+     */
+    virtual status_t dumpCamera(int fd);
+
+    /****************************************************************************
+     * Preview management.
+     ***************************************************************************/
+
+protected:
+    /* Starts preview.
+     * Note that when this method is called mPreviewWindow may be NULL,
+     * indicating that framework has an intention to start displaying video
+     * frames, but didn't create the preview window yet.
+     * Return:
+     *  NO_ERROR on success, or an appropriate error status on failure.
+     */
+    virtual status_t doStartPreview();
+
+    /* Stops preview.
+     * This method reverts DoStartPreview.
+     * Return:
+     *  NO_ERROR on success, or an appropriate error status on failure.
+     */
+    virtual status_t doStopPreview();
+
+    /****************************************************************************
+     * Private API.
+     ***************************************************************************/
+
+protected:
+    /* Cleans up camera when released. */
+    virtual status_t cleanupCamera();
+
+    /****************************************************************************
+     * Camera API callbacks as defined by camera_device_ops structure.
+     * See hardware/libhardware/include/hardware/camera.h for information on
+     * each of these callbacks. Implemented in this class, these callbacks simply
+     * dispatch the call into an instance of EmulatedCamera class defined by the
+     * 'camera_device' parameter.
+     ***************************************************************************/
+
+private:
+    static int set_preview_window(struct camera_device* dev,
+                                   struct preview_stream_ops* window);
+
+    static void set_callbacks(struct camera_device* dev,
+                              camera_notify_callback notify_cb,
+                              camera_data_callback data_cb,
+                              camera_data_timestamp_callback data_cb_timestamp,
+                              camera_request_memory get_memory,
+                              void* user);
+
+    static void enable_msg_type(struct camera_device* dev, int32_t msg_type);
+
+    static void disable_msg_type(struct camera_device* dev, int32_t msg_type);
+
+    static int msg_type_enabled(struct camera_device* dev, int32_t msg_type);
+
+    static int start_preview(struct camera_device* dev);
+
+    static void stop_preview(struct camera_device* dev);
+
+    static int preview_enabled(struct camera_device* dev);
+
+    static int store_meta_data_in_buffers(struct camera_device* dev, int enable);
+
+    static int start_recording(struct camera_device* dev);
+
+    static void stop_recording(struct camera_device* dev);
+
+    static int recording_enabled(struct camera_device* dev);
+
+    static void release_recording_frame(struct camera_device* dev,
+                                        const void* opaque);
+
+    static int auto_focus(struct camera_device* dev);
+
+    static int cancel_auto_focus(struct camera_device* dev);
+
+    static int take_picture(struct camera_device* dev);
+
+    static int cancel_picture(struct camera_device* dev);
+
+    static int set_parameters(struct camera_device* dev, const char* parms);
+
+    static char* get_parameters(struct camera_device* dev);
+
+    static void put_parameters(struct camera_device* dev, char* params);
+
+    static int send_command(struct camera_device* dev,
+                            int32_t cmd,
+                            int32_t arg1,
+                            int32_t arg2);
+
+    static void release(struct camera_device* dev);
+
+    static int dump(struct camera_device* dev, int fd);
+
+    static int close(struct hw_device_t* device);
+
+    /****************************************************************************
+     * Data members
+     ***************************************************************************/
+
+protected:
+    /* Locks this instance for parameters, state, etc. change. */
+    Mutex                           mObjectLock;
+
+    /* Camera parameters. */
+    CameraParameters                mParameters;
+
+    /* Preview window. */
+    PreviewWindow                   mPreviewWindow;
+
+    /* Callback notifier. */
+    CallbackNotifier                mCallbackNotifier;
+
+private:
+    /* Registered callbacks implementing camera API. */
+    static camera_device_ops_t      mDeviceOps;
+
+    /****************************************************************************
+     * Common keys
+     ***************************************************************************/
+
+public:
+    static const char FACING_KEY[];
+    static const char ORIENTATION_KEY[];
+    static const char RECORDING_HINT_KEY[];
+
+     /****************************************************************************
+     * Common string values
+     ***************************************************************************/
+
+    /* Possible values for FACING_KEY */
+    static const char FACING_BACK[];
+    static const char FACING_FRONT[];
+};
+
+}; /* namespace android */
+
+#endif  /* HW_EMULATOR_CAMERA_EMULATED_CAMERA_H */
diff --git a/camera/EmulatedCamera2.cpp b/camera/EmulatedCamera2.cpp
new file mode 100644
index 0000000..bbc1740
--- /dev/null
+++ b/camera/EmulatedCamera2.cpp
@@ -0,0 +1,408 @@
+/*
+ * Copyright (C) 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.
+ */
+
+/*
+ * Contains implementation of a class EmulatedCamera that encapsulates
+ * functionality common to all version 2.0 emulated camera devices.  Instances
+ * of this class (for each emulated camera) are created during the construction
+ * of the EmulatedCameraFactory instance.  This class serves as an entry point
+ * for all camera API calls that defined by camera2_device_ops_t API.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "EmulatedCamera2_Camera"
+#include <cutils/log.h>
+
+#include "EmulatedCamera2.h"
+#include "system/camera_metadata.h"
+
+namespace android {
+
+/* Constructs EmulatedCamera2 instance.
+ * Param:
+ *  cameraId - Zero based camera identifier, which is an index of the camera
+ *      instance in camera factory's array.
+ *  module - Emulated camera HAL module descriptor.
+ */
+EmulatedCamera2::EmulatedCamera2(int cameraId,
+        struct hw_module_t* module):
+        EmulatedBaseCamera(cameraId,
+                CAMERA_DEVICE_API_VERSION_2_0,
+                &common,
+                module)
+{
+    common.close = EmulatedCamera2::close;
+    ops = &sDeviceOps;
+    priv = this;
+
+    mNotifyCb = NULL;
+
+    mRequestQueueSrc = NULL;
+    mFrameQueueDst = NULL;
+
+    mVendorTagOps.get_camera_vendor_section_name =
+            EmulatedCamera2::get_camera_vendor_section_name;
+    mVendorTagOps.get_camera_vendor_tag_name =
+            EmulatedCamera2::get_camera_vendor_tag_name;
+    mVendorTagOps.get_camera_vendor_tag_type =
+            EmulatedCamera2::get_camera_vendor_tag_type;
+    mVendorTagOps.parent = this;
+}
+
+/* Destructs EmulatedCamera2 instance. */
+EmulatedCamera2::~EmulatedCamera2() {
+}
+
+/****************************************************************************
+ * Abstract API
+ ***************************************************************************/
+
+/****************************************************************************
+ * Public API
+ ***************************************************************************/
+
+status_t EmulatedCamera2::Initialize() {
+    return NO_ERROR;
+}
+
+/****************************************************************************
+ * Camera API implementation
+ ***************************************************************************/
+
+status_t EmulatedCamera2::connectCamera(hw_device_t** device) {
+    *device = &common;
+    return NO_ERROR;
+}
+
+status_t EmulatedCamera2::closeCamera() {
+    return NO_ERROR;
+}
+
+status_t EmulatedCamera2::getCameraInfo(struct camera_info* info) {
+    return EmulatedBaseCamera::getCameraInfo(info);
+}
+
+/****************************************************************************
+ * Camera Device API implementation.
+ * These methods are called from the camera API callback routines.
+ ***************************************************************************/
+
+/** Request input queue */
+
+int EmulatedCamera2::requestQueueNotify() {
+    return INVALID_OPERATION;
+}
+
+/** Count of requests in flight */
+int EmulatedCamera2::getInProgressCount() {
+    return INVALID_OPERATION;
+}
+
+/** Cancel all captures in flight */
+int EmulatedCamera2::flushCapturesInProgress() {
+    return INVALID_OPERATION;
+}
+
+/** Construct a default request for a given use case */
+int EmulatedCamera2::constructDefaultRequest(
+        int request_template,
+        camera_metadata_t **request) {
+    return INVALID_OPERATION;
+}
+
+/** Output stream creation and management */
+
+int EmulatedCamera2::allocateStream(
+        uint32_t width,
+        uint32_t height,
+        int format,
+        const camera2_stream_ops_t *stream_ops,
+        uint32_t *stream_id,
+        uint32_t *format_actual,
+        uint32_t *usage,
+        uint32_t *max_buffers) {
+    return INVALID_OPERATION;
+}
+
+int EmulatedCamera2::registerStreamBuffers(
+        uint32_t stream_id,
+        int num_buffers,
+        buffer_handle_t *buffers) {
+    return INVALID_OPERATION;
+}
+
+
+int EmulatedCamera2::releaseStream(uint32_t stream_id) {
+    return INVALID_OPERATION;
+}
+
+/** Reprocessing input stream management */
+
+int EmulatedCamera2::allocateReprocessStream(
+        uint32_t width,
+        uint32_t height,
+        uint32_t format,
+        const camera2_stream_in_ops_t *reprocess_stream_ops,
+        uint32_t *stream_id,
+        uint32_t *consumer_usage,
+        uint32_t *max_buffers) {
+    return INVALID_OPERATION;
+}
+
+int EmulatedCamera2::allocateReprocessStreamFromStream(
+        uint32_t output_stream_id,
+        const camera2_stream_in_ops_t *reprocess_stream_ops,
+        uint32_t *stream_id) {
+    return INVALID_OPERATION;
+}
+
+int EmulatedCamera2::releaseReprocessStream(uint32_t stream_id) {
+    return INVALID_OPERATION;
+}
+
+/** 3A triggering */
+
+int EmulatedCamera2::triggerAction(uint32_t trigger_id,
+                                   int ext1, int ext2) {
+    return INVALID_OPERATION;
+}
+
+/** Custom tag query methods */
+
+const char* EmulatedCamera2::getVendorSectionName(uint32_t tag) {
+    return NULL;
+}
+
+const char* EmulatedCamera2::getVendorTagName(uint32_t tag) {
+    return NULL;
+}
+
+int EmulatedCamera2::getVendorTagType(uint32_t tag) {
+    return -1;
+}
+
+/** Debug methods */
+
+int EmulatedCamera2::dump(int fd) {
+    return INVALID_OPERATION;
+}
+
+/****************************************************************************
+ * Private API.
+ ***************************************************************************/
+
+/****************************************************************************
+ * Camera API callbacks as defined by camera2_device_ops structure.  See
+ * hardware/libhardware/include/hardware/camera2.h for information on each
+ * of these callbacks. Implemented in this class, these callbacks simply
+ * dispatch the call into an instance of EmulatedCamera2 class defined by the
+ * 'camera_device2' parameter, or set a member value in the same.
+ ***************************************************************************/
+
+EmulatedCamera2* getInstance(const camera2_device_t *d) {
+    const EmulatedCamera2* cec = static_cast<const EmulatedCamera2*>(d);
+    return const_cast<EmulatedCamera2*>(cec);
+}
+
+int EmulatedCamera2::set_request_queue_src_ops(const camera2_device_t *d,
+        const camera2_request_queue_src_ops *queue_src_ops) {
+    EmulatedCamera2* ec = getInstance(d);
+    ec->mRequestQueueSrc = queue_src_ops;
+    return NO_ERROR;
+}
+
+int EmulatedCamera2::notify_request_queue_not_empty(const camera2_device_t *d) {
+    EmulatedCamera2* ec = getInstance(d);
+    return ec->requestQueueNotify();
+}
+
+int EmulatedCamera2::set_frame_queue_dst_ops(const camera2_device_t *d,
+        const camera2_frame_queue_dst_ops *queue_dst_ops) {
+    EmulatedCamera2* ec = getInstance(d);
+    ec->mFrameQueueDst = queue_dst_ops;
+    return NO_ERROR;
+}
+
+int EmulatedCamera2::get_in_progress_count(const camera2_device_t *d) {
+    EmulatedCamera2* ec = getInstance(d);
+    return ec->getInProgressCount();
+}
+
+int EmulatedCamera2::flush_captures_in_progress(const camera2_device_t *d) {
+    EmulatedCamera2* ec = getInstance(d);
+    return ec->flushCapturesInProgress();
+}
+
+int EmulatedCamera2::construct_default_request(const camera2_device_t *d,
+        int request_template,
+        camera_metadata_t **request) {
+    EmulatedCamera2* ec = getInstance(d);
+    return ec->constructDefaultRequest(request_template, request);
+}
+
+int EmulatedCamera2::allocate_stream(const camera2_device_t *d,
+        uint32_t width,
+        uint32_t height,
+        int format,
+        const camera2_stream_ops_t *stream_ops,
+        uint32_t *stream_id,
+        uint32_t *format_actual,
+        uint32_t *usage,
+        uint32_t *max_buffers) {
+    EmulatedCamera2* ec = getInstance(d);
+    return ec->allocateStream(width, height, format, stream_ops,
+            stream_id, format_actual, usage, max_buffers);
+}
+
+int EmulatedCamera2::register_stream_buffers(const camera2_device_t *d,
+        uint32_t stream_id,
+        int num_buffers,
+        buffer_handle_t *buffers) {
+    EmulatedCamera2* ec = getInstance(d);
+    return ec->registerStreamBuffers(stream_id,
+            num_buffers,
+            buffers);
+}
+int EmulatedCamera2::release_stream(const camera2_device_t *d,
+        uint32_t stream_id) {
+    EmulatedCamera2* ec = getInstance(d);
+    return ec->releaseStream(stream_id);
+}
+
+int EmulatedCamera2::allocate_reprocess_stream(const camera2_device_t *d,
+        uint32_t width,
+        uint32_t height,
+        uint32_t format,
+        const camera2_stream_in_ops_t *reprocess_stream_ops,
+        uint32_t *stream_id,
+        uint32_t *consumer_usage,
+        uint32_t *max_buffers) {
+    EmulatedCamera2* ec = getInstance(d);
+    return ec->allocateReprocessStream(width, height, format,
+            reprocess_stream_ops, stream_id, consumer_usage, max_buffers);
+}
+
+int EmulatedCamera2::allocate_reprocess_stream_from_stream(
+            const camera2_device_t *d,
+            uint32_t output_stream_id,
+            const camera2_stream_in_ops_t *reprocess_stream_ops,
+            uint32_t *stream_id) {
+    EmulatedCamera2* ec = getInstance(d);
+    return ec->allocateReprocessStreamFromStream(output_stream_id,
+            reprocess_stream_ops, stream_id);
+}
+
+
+int EmulatedCamera2::release_reprocess_stream(const camera2_device_t *d,
+        uint32_t stream_id) {
+    EmulatedCamera2* ec = getInstance(d);
+    return ec->releaseReprocessStream(stream_id);
+}
+
+int EmulatedCamera2::trigger_action(const camera2_device_t *d,
+        uint32_t trigger_id,
+        int ext1,
+        int ext2) {
+    EmulatedCamera2* ec = getInstance(d);
+    return ec->triggerAction(trigger_id, ext1, ext2);
+}
+
+int EmulatedCamera2::set_notify_callback(const camera2_device_t *d,
+        camera2_notify_callback notify_cb, void* user) {
+    EmulatedCamera2* ec = getInstance(d);
+    Mutex::Autolock l(ec->mMutex);
+    ec->mNotifyCb = notify_cb;
+    ec->mNotifyUserPtr = user;
+    return NO_ERROR;
+}
+
+int EmulatedCamera2::get_metadata_vendor_tag_ops(const camera2_device_t *d,
+        vendor_tag_query_ops_t **ops) {
+    EmulatedCamera2* ec = getInstance(d);
+    *ops = static_cast<vendor_tag_query_ops_t*>(
+            &ec->mVendorTagOps);
+    return NO_ERROR;
+}
+
+const char* EmulatedCamera2::get_camera_vendor_section_name(
+        const vendor_tag_query_ops_t *v,
+        uint32_t tag) {
+    EmulatedCamera2* ec = static_cast<const TagOps*>(v)->parent;
+    return ec->getVendorSectionName(tag);
+}
+
+const char* EmulatedCamera2::get_camera_vendor_tag_name(
+        const vendor_tag_query_ops_t *v,
+        uint32_t tag) {
+    EmulatedCamera2* ec = static_cast<const TagOps*>(v)->parent;
+    return ec->getVendorTagName(tag);
+}
+
+int EmulatedCamera2::get_camera_vendor_tag_type(
+        const vendor_tag_query_ops_t *v,
+        uint32_t tag)  {
+    EmulatedCamera2* ec = static_cast<const TagOps*>(v)->parent;
+    return ec->getVendorTagType(tag);
+}
+
+int EmulatedCamera2::dump(const camera2_device_t *d, int fd) {
+    EmulatedCamera2* ec = getInstance(d);
+    return ec->dump(fd);
+}
+
+int EmulatedCamera2::close(struct hw_device_t* device) {
+    EmulatedCamera2* ec =
+            static_cast<EmulatedCamera2*>(
+                reinterpret_cast<camera2_device_t*>(device) );
+    if (ec == NULL) {
+        ALOGE("%s: Unexpected NULL camera2 device", __FUNCTION__);
+        return -EINVAL;
+    }
+    return ec->closeCamera();
+}
+
+void EmulatedCamera2::sendNotification(int32_t msgType,
+        int32_t ext1, int32_t ext2, int32_t ext3) {
+    camera2_notify_callback notifyCb;
+    {
+        Mutex::Autolock l(mMutex);
+        notifyCb = mNotifyCb;
+    }
+    if (notifyCb != NULL) {
+        notifyCb(msgType, ext1, ext2, ext3, mNotifyUserPtr);
+    }
+}
+
+camera2_device_ops_t EmulatedCamera2::sDeviceOps = {
+    EmulatedCamera2::set_request_queue_src_ops,
+    EmulatedCamera2::notify_request_queue_not_empty,
+    EmulatedCamera2::set_frame_queue_dst_ops,
+    EmulatedCamera2::get_in_progress_count,
+    EmulatedCamera2::flush_captures_in_progress,
+    EmulatedCamera2::construct_default_request,
+    EmulatedCamera2::allocate_stream,
+    EmulatedCamera2::register_stream_buffers,
+    EmulatedCamera2::release_stream,
+    EmulatedCamera2::allocate_reprocess_stream,
+    EmulatedCamera2::allocate_reprocess_stream_from_stream,
+    EmulatedCamera2::release_reprocess_stream,
+    EmulatedCamera2::trigger_action,
+    EmulatedCamera2::set_notify_callback,
+    EmulatedCamera2::get_metadata_vendor_tag_ops,
+    EmulatedCamera2::dump
+};
+
+}; /* namespace android */
diff --git a/camera/EmulatedCamera2.h b/camera/EmulatedCamera2.h
new file mode 100644
index 0000000..755ed0e
--- /dev/null
+++ b/camera/EmulatedCamera2.h
@@ -0,0 +1,272 @@
+/*
+ * Copyright (C) 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.
+ */
+
+#ifndef HW_EMULATOR_CAMERA_EMULATED_CAMERA2_H
+#define HW_EMULATOR_CAMERA_EMULATED_CAMERA2_H
+
+/*
+ * Contains declaration of a class EmulatedCamera that encapsulates
+ * functionality common to all version 2.0 emulated camera devices.  Instances
+ * of this class (for each emulated camera) are created during the construction
+ * of the EmulatedCameraFactory instance.  This class serves as an entry point
+ * for all camera API calls that defined by camera2_device_ops_t API.
+ */
+
+#include "hardware/camera2.h"
+#include "system/camera_metadata.h"
+#include "EmulatedBaseCamera.h"
+#include <utils/Thread.h>
+#include <utils/Mutex.h>
+
+namespace android {
+
+/* Encapsulates functionality common to all version 2.0 emulated camera devices
+ *
+ * Note that EmulatedCameraFactory instantiates object of this class just once,
+ * when EmulatedCameraFactory instance gets constructed. Connection to /
+ * disconnection from the actual camera device is handled by calls to
+ * connectDevice(), and closeCamera() methods of this class that are invoked in
+ * response to hw_module_methods_t::open, and camera_device::close callbacks.
+ */
+class EmulatedCamera2 : public camera2_device, public EmulatedBaseCamera {
+public:
+    /* Constructs EmulatedCamera2 instance.
+     * Param:
+     *  cameraId - Zero based camera identifier, which is an index of the camera
+     *      instance in camera factory's array.
+     *  module - Emulated camera HAL module descriptor.
+     */
+    EmulatedCamera2(int cameraId,
+            struct hw_module_t* module);
+
+    /* Destructs EmulatedCamera2 instance. */
+    virtual ~EmulatedCamera2();
+
+    /****************************************************************************
+     * Abstract API
+     ***************************************************************************/
+
+public:
+
+    /****************************************************************************
+     * Public API
+     ***************************************************************************/
+
+public:
+    virtual status_t Initialize();
+
+    /****************************************************************************
+     * Camera module API and generic hardware device API implementation
+     ***************************************************************************/
+
+public:
+    virtual status_t connectCamera(hw_device_t** device);
+
+    virtual status_t closeCamera();
+
+    virtual status_t getCameraInfo(struct camera_info* info) = 0;
+
+    /****************************************************************************
+     * Camera API implementation.
+     * These methods are called from the camera API callback routines.
+     ***************************************************************************/
+
+protected:
+    /** Request input queue notification */
+    virtual int requestQueueNotify();
+
+    /** Count of requests in flight */
+    virtual int getInProgressCount();
+
+    /** Cancel all captures in flight */
+    virtual int flushCapturesInProgress();
+
+    virtual int constructDefaultRequest(
+        int request_template,
+        camera_metadata_t **request);
+
+    /** Output stream creation and management */
+    virtual int allocateStream(
+            uint32_t width,
+            uint32_t height,
+            int format,
+            const camera2_stream_ops_t *stream_ops,
+            uint32_t *stream_id,
+            uint32_t *format_actual,
+            uint32_t *usage,
+            uint32_t *max_buffers);
+
+    virtual int registerStreamBuffers(
+            uint32_t stream_id,
+            int num_buffers,
+            buffer_handle_t *buffers);
+
+    virtual int releaseStream(uint32_t stream_id);
+
+    /** Input stream creation and management */
+    virtual int allocateReprocessStream(
+            uint32_t width,
+            uint32_t height,
+            uint32_t format,
+            const camera2_stream_in_ops_t *reprocess_stream_ops,
+            uint32_t *stream_id,
+            uint32_t *consumer_usage,
+            uint32_t *max_buffers);
+
+    virtual int allocateReprocessStreamFromStream(
+            uint32_t output_stream_id,
+            const camera2_stream_in_ops_t *reprocess_stream_ops,
+            uint32_t *stream_id);
+
+    virtual int releaseReprocessStream(uint32_t stream_id);
+
+    /** 3A action triggering */
+    virtual int triggerAction(uint32_t trigger_id,
+            int32_t ext1, int32_t ext2);
+
+    /** Custom tag definitions */
+    virtual const char* getVendorSectionName(uint32_t tag);
+    virtual const char* getVendorTagName(uint32_t tag);
+    virtual int         getVendorTagType(uint32_t tag);
+
+    /** Debug methods */
+
+    virtual int dump(int fd);
+
+    /****************************************************************************
+     * Camera API callbacks as defined by camera2_device_ops structure.  See
+     * hardware/libhardware/include/hardware/camera2.h for information on each
+     * of these callbacks. Implemented in this class, these callbacks simply
+     * dispatch the call into an instance of EmulatedCamera2 class defined in
+     * the 'camera_device2' parameter.
+     ***************************************************************************/
+
+private:
+    /** Input request queue */
+    static int set_request_queue_src_ops(const camera2_device_t *,
+            const camera2_request_queue_src_ops *queue_src_ops);
+    static int notify_request_queue_not_empty(const camera2_device_t *);
+
+    /** Output frame queue */
+    static int set_frame_queue_dst_ops(const camera2_device_t *,
+            const camera2_frame_queue_dst_ops *queue_dst_ops);
+
+    /** In-progress request management */
+    static int get_in_progress_count(const camera2_device_t *);
+
+    static int flush_captures_in_progress(const camera2_device_t *);
+
+    /** Request template creation */
+    static int construct_default_request(const camera2_device_t *,
+            int request_template,
+            camera_metadata_t **request);
+
+    /** Stream management */
+    static int allocate_stream(const camera2_device_t *,
+            uint32_t width,
+            uint32_t height,
+            int format,
+            const camera2_stream_ops_t *stream_ops,
+            uint32_t *stream_id,
+            uint32_t *format_actual,
+            uint32_t *usage,
+            uint32_t *max_buffers);
+
+    static int register_stream_buffers(const camera2_device_t *,
+            uint32_t stream_id,
+            int num_buffers,
+            buffer_handle_t *buffers);
+
+    static int release_stream(const camera2_device_t *,
+            uint32_t stream_id);
+
+    static int allocate_reprocess_stream(const camera2_device_t *,
+            uint32_t width,
+            uint32_t height,
+            uint32_t format,
+            const camera2_stream_in_ops_t *reprocess_stream_ops,
+            uint32_t *stream_id,
+            uint32_t *consumer_usage,
+            uint32_t *max_buffers);
+
+    static int allocate_reprocess_stream_from_stream(const camera2_device_t *,
+            uint32_t output_stream_id,
+            const camera2_stream_in_ops_t *reprocess_stream_ops,
+            uint32_t *stream_id);
+
+    static int release_reprocess_stream(const camera2_device_t *,
+            uint32_t stream_id);
+
+    /** 3A triggers*/
+    static int trigger_action(const camera2_device_t *,
+            uint32_t trigger_id,
+            int ext1,
+            int ext2);
+
+    /** Notifications to application */
+    static int set_notify_callback(const camera2_device_t *,
+            camera2_notify_callback notify_cb,
+            void *user);
+
+    /** Vendor metadata registration */
+    static int get_metadata_vendor_tag_ops(const camera2_device_t *,
+            vendor_tag_query_ops_t **ops);
+    // for get_metadata_vendor_tag_ops
+    static const char* get_camera_vendor_section_name(
+            const vendor_tag_query_ops_t *,
+            uint32_t tag);
+    static const char* get_camera_vendor_tag_name(
+            const vendor_tag_query_ops_t *,
+            uint32_t tag);
+    static int get_camera_vendor_tag_type(
+            const vendor_tag_query_ops_t *,
+            uint32_t tag);
+
+    static int dump(const camera2_device_t *, int fd);
+
+    /** For hw_device_t ops */
+    static int close(struct hw_device_t* device);
+
+    /****************************************************************************
+     * Data members shared with implementations
+     ***************************************************************************/
+  protected:
+    /** Mutex for calls through camera2 device interface */
+    Mutex mMutex;
+
+    const camera2_request_queue_src_ops *mRequestQueueSrc;
+    const camera2_frame_queue_dst_ops *mFrameQueueDst;
+
+    struct TagOps : public vendor_tag_query_ops {
+        EmulatedCamera2 *parent;
+    };
+    TagOps      mVendorTagOps;
+
+    void sendNotification(int32_t msgType,
+            int32_t ext1, int32_t ext2, int32_t ext3);
+
+    /****************************************************************************
+     * Data members
+     ***************************************************************************/
+  private:
+    static camera2_device_ops_t sDeviceOps;
+    camera2_notify_callback mNotifyCb;
+    void* mNotifyUserPtr;
+};
+
+}; /* namespace android */
+
+#endif  /* HW_EMULATOR_CAMERA_EMULATED_CAMERA2_H */
diff --git a/camera/EmulatedCameraCommon.h b/camera/EmulatedCameraCommon.h
new file mode 100755
index 0000000..c1d575c
--- /dev/null
+++ b/camera/EmulatedCameraCommon.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef HW_EMULATOR_CAMERA_EMULATED_CAMERA_COMMON_H
+#define HW_EMULATOR_CAMERA_EMULATED_CAMERA_COMMON_H
+
+/*
+ * Contains common declarations that are used across the camera emulation.
+ */
+
+#include <linux/videodev2.h>
+#include <hardware/camera.h>
+
+/* A helper class that tracks a routine execution.
+ * Basically, it dumps an enry message in its constructor, and an exit message
+ * in its destructor. Use LOGRE() macro (declared bellow) to create instances
+ * of this class at the beginning of the tracked routines / methods.
+ */
+class HWERoutineTracker {
+public:
+    /* Constructor that prints an "entry" trace message. */
+    explicit HWERoutineTracker(const char* name)
+            : mName(name) {
+        ALOGV("Entering %s", mName);
+    }
+
+    /* Destructor that prints a "leave" trace message. */
+    ~HWERoutineTracker() {
+        ALOGV("Leaving %s", mName);
+    }
+
+private:
+    /* Stores the routine name. */
+    const char* mName;
+};
+
+/* Logs an execution of a routine / method. */
+#define LOGRE() HWERoutineTracker hwertracker_##__LINE__(__FUNCTION__)
+
+/*
+ * min / max macros
+ */
+
+#define min(a,b)    (((a) < (b)) ? (a) : (b))
+#define max(a,b)    (((a) > (b)) ? (a) : (b))
+
+#endif  /* HW_EMULATOR_CAMERA_EMULATED_CAMERA_COMMON_H */
diff --git a/camera/EmulatedCameraDevice.cpp b/camera/EmulatedCameraDevice.cpp
new file mode 100755
index 0000000..5c52808
--- /dev/null
+++ b/camera/EmulatedCameraDevice.cpp
@@ -0,0 +1,397 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+/*
+ * Contains implementation of an abstract class EmulatedCameraDevice that defines
+ * functionality expected from an emulated physical camera device:
+ *  - Obtaining and setting camera parameters
+ *  - Capturing frames
+ *  - Streaming video
+ *  - etc.
+ */
+
+#define LOG_NDEBUG 0
+#define LOG_TAG "EmulatedCamera_Device"
+#include <cutils/log.h>
+#include <sys/select.h>
+#include <cmath>
+#include "EmulatedCameraDevice.h"
+
+namespace android {
+
+const float GAMMA_CORRECTION = 2.2f;
+EmulatedCameraDevice::EmulatedCameraDevice(EmulatedCamera* camera_hal)
+    : mObjectLock(),
+      mCurFrameTimestamp(0),
+      mCameraHAL(camera_hal),
+      mCurrentFrame(NULL),
+      mExposureCompensation(1.0f),
+      mWhiteBalanceScale(NULL),
+      mSupportedWhiteBalanceScale(),
+      mState(ECDS_CONSTRUCTED)
+{
+}
+
+EmulatedCameraDevice::~EmulatedCameraDevice()
+{
+    ALOGV("EmulatedCameraDevice destructor");
+    if (mCurrentFrame != NULL) {
+        delete[] mCurrentFrame;
+    }
+    for (int i = 0; i < mSupportedWhiteBalanceScale.size(); ++i) {
+        if (mSupportedWhiteBalanceScale.valueAt(i) != NULL) {
+            delete[] mSupportedWhiteBalanceScale.valueAt(i);
+        }
+    }
+}
+
+/****************************************************************************
+ * Emulated camera device public API
+ ***************************************************************************/
+
+status_t EmulatedCameraDevice::Initialize()
+{
+    if (isInitialized()) {
+        ALOGW("%s: Emulated camera device is already initialized: mState = %d",
+             __FUNCTION__, mState);
+        return NO_ERROR;
+    }
+
+    /* Instantiate worker thread object. */
+    mWorkerThread = new WorkerThread(this);
+    if (getWorkerThread() == NULL) {
+        ALOGE("%s: Unable to instantiate worker thread object", __FUNCTION__);
+        return ENOMEM;
+    }
+
+    mState = ECDS_INITIALIZED;
+
+    return NO_ERROR;
+}
+
+status_t EmulatedCameraDevice::startDeliveringFrames(bool one_burst)
+{
+    ALOGV("%s", __FUNCTION__);
+
+    if (!isStarted()) {
+        ALOGE("%s: Device is not started", __FUNCTION__);
+        return EINVAL;
+    }
+
+    /* Frames will be delivered from the thread routine. */
+    const status_t res = startWorkerThread(one_burst);
+    ALOGE_IF(res != NO_ERROR, "%s: startWorkerThread failed", __FUNCTION__);
+    return res;
+}
+
+status_t EmulatedCameraDevice::stopDeliveringFrames()
+{
+    ALOGV("%s", __FUNCTION__);
+
+    if (!isStarted()) {
+        ALOGW("%s: Device is not started", __FUNCTION__);
+        return NO_ERROR;
+    }
+
+    const status_t res = stopWorkerThread();
+    ALOGE_IF(res != NO_ERROR, "%s: startWorkerThread failed", __FUNCTION__);
+    return res;
+}
+
+void EmulatedCameraDevice::setExposureCompensation(const float ev) {
+    ALOGV("%s", __FUNCTION__);
+
+    if (!isStarted()) {
+        ALOGW("%s: Fake camera device is not started.", __FUNCTION__);
+    }
+
+    mExposureCompensation = std::pow(2.0f, ev / GAMMA_CORRECTION);
+    ALOGV("New exposure compensation is %f", mExposureCompensation);
+}
+
+void EmulatedCameraDevice::initializeWhiteBalanceModes(const char* mode,
+                                                       const float r_scale,
+                                                       const float b_scale) {
+    ALOGV("%s with %s, %f, %f", __FUNCTION__, mode, r_scale, b_scale);
+    float* value = new float[3];
+    value[0] = r_scale; value[1] = 1.0f; value[2] = b_scale;
+    mSupportedWhiteBalanceScale.add(String8(mode), value);
+}
+
+void EmulatedCameraDevice::setWhiteBalanceMode(const char* mode) {
+    ALOGV("%s with white balance %s", __FUNCTION__, mode);
+    mWhiteBalanceScale =
+            mSupportedWhiteBalanceScale.valueFor(String8(mode));
+}
+
+/* Computes the pixel value after adjusting the white balance to the current
+ * one. The input the y, u, v channel of the pixel and the adjusted value will
+ * be stored in place. The adjustment is done in RGB space.
+ */
+void EmulatedCameraDevice::changeWhiteBalance(uint8_t& y,
+                                              uint8_t& u,
+                                              uint8_t& v) const {
+    float r_scale = mWhiteBalanceScale[0];
+    float b_scale = mWhiteBalanceScale[2];
+    int r = static_cast<float>(YUV2R(y, u, v)) / r_scale;
+    int g = YUV2G(y, u, v);
+    int b = static_cast<float>(YUV2B(y, u, v)) / b_scale;
+
+    y = RGB2Y(r, g, b);
+    u = RGB2U(r, g, b);
+    v = RGB2V(r, g, b);
+}
+
+status_t EmulatedCameraDevice::getCurrentPreviewFrame(void* buffer)
+{
+    if (!isStarted()) {
+        ALOGE("%s: Device is not started", __FUNCTION__);
+        return EINVAL;
+    }
+    if (mCurrentFrame == NULL || buffer == NULL) {
+        ALOGE("%s: No framebuffer", __FUNCTION__);
+        return EINVAL;
+    }
+
+    /* In emulation the framebuffer is never RGB. */
+    switch (mPixelFormat) {
+        case V4L2_PIX_FMT_YVU420:
+            YV12ToRGB32(mCurrentFrame, buffer, mFrameWidth, mFrameHeight);
+            return NO_ERROR;
+        case V4L2_PIX_FMT_YUV420:
+            YU12ToRGB32(mCurrentFrame, buffer, mFrameWidth, mFrameHeight);
+            return NO_ERROR;
+        case V4L2_PIX_FMT_NV21:
+            NV21ToRGB32(mCurrentFrame, buffer, mFrameWidth, mFrameHeight);
+            return NO_ERROR;
+        case V4L2_PIX_FMT_NV12:
+            NV12ToRGB32(mCurrentFrame, buffer, mFrameWidth, mFrameHeight);
+            return NO_ERROR;
+
+        default:
+            ALOGE("%s: Unknown pixel format %.4s",
+                 __FUNCTION__, reinterpret_cast<const char*>(&mPixelFormat));
+            return EINVAL;
+    }
+}
+
+/****************************************************************************
+ * Emulated camera device private API
+ ***************************************************************************/
+
+status_t EmulatedCameraDevice::commonStartDevice(int width,
+                                                 int height,
+                                                 uint32_t pix_fmt)
+{
+    /* Validate pixel format, and calculate framebuffer size at the same time. */
+    switch (pix_fmt) {
+        case V4L2_PIX_FMT_YVU420:
+        case V4L2_PIX_FMT_YUV420:
+        case V4L2_PIX_FMT_NV21:
+        case V4L2_PIX_FMT_NV12:
+            mFrameBufferSize = (width * height * 12) / 8;
+            break;
+
+        default:
+            ALOGE("%s: Unknown pixel format %.4s",
+                 __FUNCTION__, reinterpret_cast<const char*>(&pix_fmt));
+            return EINVAL;
+    }
+
+    /* Cache framebuffer info. */
+    mFrameWidth = width;
+    mFrameHeight = height;
+    mPixelFormat = pix_fmt;
+    mTotalPixels = width * height;
+
+    /* Allocate framebuffer. */
+    mCurrentFrame = new uint8_t[mFrameBufferSize];
+    if (mCurrentFrame == NULL) {
+        ALOGE("%s: Unable to allocate framebuffer", __FUNCTION__);
+        return ENOMEM;
+    }
+    ALOGV("%s: Allocated %p %d bytes for %d pixels in %.4s[%dx%d] frame",
+         __FUNCTION__, mCurrentFrame, mFrameBufferSize, mTotalPixels,
+         reinterpret_cast<const char*>(&mPixelFormat), mFrameWidth, mFrameHeight);
+    return NO_ERROR;
+}
+
+void EmulatedCameraDevice::commonStopDevice()
+{
+    mFrameWidth = mFrameHeight = mTotalPixels = 0;
+    mPixelFormat = 0;
+
+    if (mCurrentFrame != NULL) {
+        delete[] mCurrentFrame;
+        mCurrentFrame = NULL;
+    }
+}
+
+/****************************************************************************
+ * Worker thread management.
+ ***************************************************************************/
+
+status_t EmulatedCameraDevice::startWorkerThread(bool one_burst)
+{
+    ALOGV("%s", __FUNCTION__);
+
+    if (!isInitialized()) {
+        ALOGE("%s: Emulated camera device is not initialized", __FUNCTION__);
+        return EINVAL;
+    }
+
+    const status_t res = getWorkerThread()->startThread(one_burst);
+    ALOGE_IF(res != NO_ERROR, "%s: Unable to start worker thread", __FUNCTION__);
+    return res;
+}
+
+status_t EmulatedCameraDevice::stopWorkerThread()
+{
+    ALOGV("%s", __FUNCTION__);
+
+    if (!isInitialized()) {
+        ALOGE("%s: Emulated camera device is not initialized", __FUNCTION__);
+        return EINVAL;
+    }
+
+    const status_t res = getWorkerThread()->stopThread();
+    ALOGE_IF(res != NO_ERROR, "%s: Unable to stop worker thread", __FUNCTION__);
+    return res;
+}
+
+bool EmulatedCameraDevice::inWorkerThread()
+{
+    /* This will end the thread loop, and will terminate the thread. Derived
+     * classes must override this method. */
+    return false;
+}
+
+/****************************************************************************
+ * Worker thread implementation.
+ ***************************************************************************/
+
+status_t EmulatedCameraDevice::WorkerThread::readyToRun()
+{
+    ALOGV("Starting emulated camera device worker thread...");
+
+    ALOGW_IF(mThreadControl >= 0 || mControlFD >= 0,
+            "%s: Thread control FDs are opened", __FUNCTION__);
+    /* Create a pair of FDs that would be used to control the thread. */
+    int thread_fds[2];
+    if (pipe(thread_fds) == 0) {
+        mThreadControl = thread_fds[1];
+        mControlFD = thread_fds[0];
+        ALOGV("Emulated device's worker thread has been started.");
+        return NO_ERROR;
+    } else {
+        ALOGE("%s: Unable to create thread control FDs: %d -> %s",
+             __FUNCTION__, errno, strerror(errno));
+        return errno;
+    }
+}
+
+status_t EmulatedCameraDevice::WorkerThread::stopThread()
+{
+    ALOGV("Stopping emulated camera device's worker thread...");
+
+    status_t res = EINVAL;
+    if (mThreadControl >= 0) {
+        /* Send "stop" message to the thread loop. */
+        const ControlMessage msg = THREAD_STOP;
+        const int wres =
+            TEMP_FAILURE_RETRY(write(mThreadControl, &msg, sizeof(msg)));
+        if (wres == sizeof(msg)) {
+            /* Stop the thread, and wait till it's terminated. */
+            res = requestExitAndWait();
+            if (res == NO_ERROR) {
+                /* Close control FDs. */
+                if (mThreadControl >= 0) {
+                    close(mThreadControl);
+                    mThreadControl = -1;
+                }
+                if (mControlFD >= 0) {
+                    close(mControlFD);
+                    mControlFD = -1;
+                }
+                ALOGV("Emulated camera device's worker thread has been stopped.");
+            } else {
+                ALOGE("%s: requestExitAndWait failed: %d -> %s",
+                     __FUNCTION__, res, strerror(-res));
+            }
+        } else {
+            ALOGE("%s: Unable to send THREAD_STOP message: %d -> %s",
+                 __FUNCTION__, errno, strerror(errno));
+            res = errno ? errno : EINVAL;
+        }
+    } else {
+        ALOGE("%s: Thread control FDs are not opened", __FUNCTION__);
+    }
+
+    return res;
+}
+
+EmulatedCameraDevice::WorkerThread::SelectRes
+EmulatedCameraDevice::WorkerThread::Select(int fd, int timeout)
+{
+    fd_set fds[1];
+    struct timeval tv, *tvp = NULL;
+
+    const int fd_num = (fd >= 0) ? max(fd, mControlFD) + 1 :
+                                   mControlFD + 1;
+    FD_ZERO(fds);
+    FD_SET(mControlFD, fds);
+    if (fd >= 0) {
+        FD_SET(fd, fds);
+    }
+    if (timeout) {
+        tv.tv_sec = timeout / 1000000;
+        tv.tv_usec = timeout % 1000000;
+        tvp = &tv;
+    }
+    int res = TEMP_FAILURE_RETRY(select(fd_num, fds, NULL, NULL, tvp));
+    if (res < 0) {
+        ALOGE("%s: select returned %d and failed: %d -> %s",
+             __FUNCTION__, res, errno, strerror(errno));
+        return ERROR;
+    } else if (res == 0) {
+        /* Timeout. */
+        return TIMEOUT;
+    } else if (FD_ISSET(mControlFD, fds)) {
+        /* A control event. Lets read the message. */
+        ControlMessage msg;
+        res = TEMP_FAILURE_RETRY(read(mControlFD, &msg, sizeof(msg)));
+        if (res != sizeof(msg)) {
+            ALOGE("%s: Unexpected message size %d, or an error %d -> %s",
+                 __FUNCTION__, res, errno, strerror(errno));
+            return ERROR;
+        }
+        /* THREAD_STOP is the only message expected here. */
+        if (msg == THREAD_STOP) {
+            ALOGV("%s: THREAD_STOP message is received", __FUNCTION__);
+            return EXIT_THREAD;
+        } else {
+            ALOGE("Unknown worker thread message %d", msg);
+            return ERROR;
+        }
+    } else {
+        /* Must be an FD. */
+        ALOGW_IF(fd < 0 || !FD_ISSET(fd, fds), "%s: Undefined 'select' result",
+                __FUNCTION__);
+        return READY;
+    }
+}
+
+};  /* namespace android */
diff --git a/camera/EmulatedCameraDevice.h b/camera/EmulatedCameraDevice.h
new file mode 100755
index 0000000..b7cdcb7
--- /dev/null
+++ b/camera/EmulatedCameraDevice.h
@@ -0,0 +1,544 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef HW_EMULATOR_CAMERA_EMULATED_CAMERA_DEVICE_H
+#define HW_EMULATOR_CAMERA_EMULATED_CAMERA_DEVICE_H
+
+/*
+ * Contains declaration of an abstract class EmulatedCameraDevice that defines
+ * functionality expected from an emulated physical camera device:
+ *  - Obtaining and setting camera device parameters
+ *  - Capturing frames
+ *  - Streaming video
+ *  - etc.
+ */
+
+#include <utils/threads.h>
+#include <utils/KeyedVector.h>
+#include <utils/String8.h>
+#include "EmulatedCameraCommon.h"
+#include "Converters.h"
+
+namespace android {
+
+class EmulatedCamera;
+
+/* Encapsulates an abstract class EmulatedCameraDevice that defines
+ * functionality expected from an emulated physical camera device:
+ *  - Obtaining and setting camera device parameters
+ *  - Capturing frames
+ *  - Streaming video
+ *  - etc.
+ */
+class EmulatedCameraDevice {
+public:
+    /* Constructs EmulatedCameraDevice instance.
+     * Param:
+     *  camera_hal - Emulated camera that implements the camera HAL API, and
+     *      manages (contains) this object.
+     */
+    explicit EmulatedCameraDevice(EmulatedCamera* camera_hal);
+
+    /* Destructs EmulatedCameraDevice instance. */
+    virtual ~EmulatedCameraDevice();
+
+    /***************************************************************************
+     * Emulated camera device abstract interface
+     **************************************************************************/
+
+public:
+    /* Connects to the camera device.
+     * This method must be called on an initialized instance of this class.
+     * Return:
+     *  NO_ERROR on success, or an appropriate error status.
+     */
+    virtual status_t connectDevice() = 0;
+
+    /* Disconnects from the camera device.
+     * Return:
+     *  NO_ERROR on success, or an appropriate error status. If this method is
+     *  called for already disconnected, or uninitialized instance of this class,
+     *  a successful status must be returned from this method. If this method is
+     *  called for an instance that is in the "started" state, this method must
+     *  return a failure.
+     */
+    virtual status_t disconnectDevice() = 0;
+
+    /* Starts the camera device.
+     * This method tells the camera device to start capturing frames of the given
+     * dimensions for the given pixel format. Note that this method doesn't start
+     * the delivery of the captured frames to the emulated camera. Call
+     * startDeliveringFrames method to start delivering frames. This method must
+     * be called on a connected instance of this class. If it is called on a
+     * disconnected instance, this method must return a failure.
+     * Param:
+     *  width, height - Frame dimensions to use when capturing video frames.
+     *  pix_fmt - Pixel format to use when capturing video frames.
+     * Return:
+     *  NO_ERROR on success, or an appropriate error status.
+     */
+    virtual status_t startDevice(int width, int height, uint32_t pix_fmt) = 0;
+
+    /* Stops the camera device.
+     * This method tells the camera device to stop capturing frames. Note that
+     * this method doesn't stop delivering frames to the emulated camera. Always
+     * call stopDeliveringFrames prior to calling this method.
+     * Return:
+     *  NO_ERROR on success, or an appropriate error status. If this method is
+     *  called for an object that is not capturing frames, or is disconnected,
+     *  or is uninitialized, a successful status must be returned from this
+     *  method.
+     */
+    virtual status_t stopDevice() = 0;
+
+    /***************************************************************************
+     * Emulated camera device public API
+     **************************************************************************/
+
+public:
+    /* Initializes EmulatedCameraDevice instance.
+     * Derived classes should override this method in order to cache static
+     * properties of the physical device (list of supported pixel formats, frame
+     * sizes, etc.) If this method is called on an already initialized instance,
+     * it must return a successful status.
+     * Return:
+     *  NO_ERROR on success, or an appropriate error status.
+     */
+    virtual status_t Initialize();
+
+    /* Initializes the white balance modes parameters.
+     * The parameters are passed by each individual derived camera API to
+     * represent that different camera manufacturers may have different
+     * preferences on the white balance parameters. Green channel in the RGB
+     * color space is fixed to keep the luminance to be reasonably constant.
+     *
+     * Param:
+     * mode the text describing the current white balance mode
+     * r_scale the scale factor for the R channel in RGB space
+     * b_scale the scale factor for the B channel in RGB space.
+     */
+    void initializeWhiteBalanceModes(const char* mode,
+                                     const float r_scale,
+                                     const float b_scale);
+
+    /* Starts delivering frames captured from the camera device.
+     * This method will start the worker thread that would be pulling frames from
+     * the camera device, and will deliver the pulled frames back to the emulated
+     * camera via onNextFrameAvailable callback. This method must be called on a
+     * connected instance of this class with a started camera device. If it is
+     * called on a disconnected instance, or camera device has not been started,
+     * this method must return a failure.
+     * Param:
+     *  one_burst - Controls how many frames should be delivered. If this
+     *      parameter is 'true', only one captured frame will be delivered to the
+     *      emulated camera. If this parameter is 'false', frames will keep
+     *      coming until stopDeliveringFrames method is called. Typically, this
+     *      parameter is set to 'true' only in order to obtain a single frame
+     *      that will be used as a "picture" in takePicture method of the
+     *      emulated camera.
+     * Return:
+     *  NO_ERROR on success, or an appropriate error status.
+     */
+    virtual status_t startDeliveringFrames(bool one_burst);
+
+    /* Stops delivering frames captured from the camera device.
+     * This method will stop the worker thread started by startDeliveringFrames.
+     * Return:
+     *  NO_ERROR on success, or an appropriate error status.
+     */
+    virtual status_t stopDeliveringFrames();
+
+    /* Sets the exposure compensation for the camera device.
+     */
+    void setExposureCompensation(const float ev);
+
+    /* Sets the white balance mode for the device.
+     */
+    void setWhiteBalanceMode(const char* mode);
+
+    /* Gets current framebuffer, converted into preview frame format.
+     * This method must be called on a connected instance of this class with a
+     * started camera device. If it is called on a disconnected instance, or
+     * camera device has not been started, this method must return a failure.
+     * Note that this method should be called only after at least one frame has
+     * been captured and delivered. Otherwise it will return garbage in the
+     * preview frame buffer. Typically, this method shuld be called from
+     * onNextFrameAvailable callback.
+     * Param:
+     *  buffer - Buffer, large enough to contain the entire preview frame.
+     * Return:
+     *  NO_ERROR on success, or an appropriate error status.
+     */
+    virtual status_t getCurrentPreviewFrame(void* buffer);
+
+    /* Gets width of the frame obtained from the physical device.
+     * Return:
+     *  Width of the frame obtained from the physical device. Note that value
+     *  returned from this method is valid only in case if camera device has been
+     *  started.
+     */
+    inline int getFrameWidth() const
+    {
+        ALOGE_IF(!isStarted(), "%s: Device is not started", __FUNCTION__);
+        return mFrameWidth;
+    }
+
+    /* Gets height of the frame obtained from the physical device.
+     * Return:
+     *  Height of the frame obtained from the physical device. Note that value
+     *  returned from this method is valid only in case if camera device has been
+     *  started.
+     */
+    inline int getFrameHeight() const
+    {
+        ALOGE_IF(!isStarted(), "%s: Device is not started", __FUNCTION__);
+        return mFrameHeight;
+    }
+
+    /* Gets byte size of the current frame buffer.
+     * Return:
+     *  Byte size of the frame buffer. Note that value returned from this method
+     *  is valid only in case if camera device has been started.
+     */
+    inline size_t getFrameBufferSize() const
+    {
+        ALOGE_IF(!isStarted(), "%s: Device is not started", __FUNCTION__);
+        return mFrameBufferSize;
+    }
+
+    /* Gets number of pixels in the current frame buffer.
+     * Return:
+     *  Number of pixels in the frame buffer. Note that value returned from this
+     *  method is valid only in case if camera device has been started.
+     */
+    inline int getPixelNum() const
+    {
+        ALOGE_IF(!isStarted(), "%s: Device is not started", __FUNCTION__);
+        return mTotalPixels;
+    }
+
+    /* Gets pixel format of the frame that camera device streams to this class.
+     * Throughout camera framework, there are three different forms of pixel
+     * format representation:
+     *  - Original format, as reported by the actual camera device. Values for
+     *    this format are declared in bionic/libc/kernel/common/linux/videodev2.h
+     *  - String representation as defined in CameraParameters::PIXEL_FORMAT_XXX
+     *    strings in frameworks/base/include/camera/CameraParameters.h
+     *  - HAL_PIXEL_FORMAT_XXX format, as defined in system/core/include/system/graphics.h
+     * Since emulated camera device gets its data from the actual device, it gets
+     * pixel format in the original form. And that's the pixel format
+     * representation that will be returned from this method. HAL components will
+     * need to translate value returned from this method to the appropriate form.
+     * This method must be called only on started instance of this class, since
+     * it's applicable only when camera device is ready to stream frames.
+     * Param:
+     *  pix_fmt - Upon success contains the original pixel format.
+     * Return:
+     *  Current framebuffer's pixel format. Note that value returned from this
+     *  method is valid only in case if camera device has been started.
+     */
+    inline uint32_t getOriginalPixelFormat() const
+    {
+        ALOGE_IF(!isStarted(), "%s: Device is not started", __FUNCTION__);
+        return mPixelFormat;
+    }
+
+    /*
+     * State checkers.
+     */
+
+    inline bool isInitialized() const {
+        /* Instance is initialized when the worker thread has been successfuly
+         * created (but not necessarily started). */
+        return mWorkerThread.get() != NULL && mState != ECDS_CONSTRUCTED;
+    }
+    inline bool isConnected() const {
+        /* Instance is connected when its status is either"connected", or
+         * "started". */
+        return mState == ECDS_CONNECTED || mState == ECDS_STARTED;
+    }
+    inline bool isStarted() const {
+        return mState == ECDS_STARTED;
+    }
+
+    /****************************************************************************
+     * Emulated camera device private API
+     ***************************************************************************/
+protected:
+    /* Performs common validation and calculation of startDevice parameters.
+     * Param:
+     *  width, height, pix_fmt - Parameters passed to the startDevice method.
+     * Return:
+     *  NO_ERROR on success, or an appropriate error status.
+     */
+    virtual status_t commonStartDevice(int width, int height, uint32_t pix_fmt);
+
+    /* Performs common cleanup on stopDevice.
+     * This method will undo what commonStartDevice had done.
+     */
+    virtual void commonStopDevice();
+
+    /** Computes a luminance value after taking the exposure compensation.
+     * value into account.
+     *
+     * Param:
+     * inputY - The input luminance value.
+     * Return:
+     * The luminance value after adjusting the exposure compensation.
+     */
+    inline uint8_t changeExposure(const uint8_t& inputY) const {
+        return static_cast<uint8_t>(clamp(static_cast<float>(inputY) *
+                                    mExposureCompensation));
+    }
+
+    /** Computes the pixel value in YUV space after adjusting to the current
+     * white balance mode.
+     */
+    void changeWhiteBalance(uint8_t& y, uint8_t& u, uint8_t& v) const;
+
+    /****************************************************************************
+     * Worker thread management.
+     * Typicaly when emulated camera device starts capturing frames from the
+     * actual device, it does that in a worker thread created in StartCapturing,
+     * and terminated in StopCapturing. Since this is such a typical scenario,
+     * it makes sence to encapsulate worker thread management in the base class
+     * for all emulated camera devices.
+     ***************************************************************************/
+
+protected:
+    /* Starts the worker thread.
+     * Typically, worker thread is started from startDeliveringFrames method of
+     * this class.
+     * Param:
+     *  one_burst - Controls how many times thread loop should run. If this
+     *      parameter is 'true', thread routine will run only once If this
+     *      parameter is 'false', thread routine will run until stopWorkerThread
+     *      method is called. See startDeliveringFrames for more info.
+     * Return:
+     *  NO_ERROR on success, or an appropriate error status.
+     */
+    virtual status_t startWorkerThread(bool one_burst);
+
+    /* Stops the worker thread.
+     * Note that this method will always wait for the worker thread to terminate.
+     * Typically, worker thread is started from stopDeliveringFrames method of
+     * this class.
+     * Return:
+     *  NO_ERROR on success, or an appropriate error status.
+     */
+    virtual status_t stopWorkerThread();
+
+    /* Implementation of the worker thread routine.
+     * In the default implementation of the worker thread routine we simply
+     * return 'false' forcing the thread loop to exit, and the thread to
+     * terminate. Derived class should override that method to provide there the
+     * actual frame delivery.
+     * Return:
+     *  true To continue thread loop (this method will be called again), or false
+     *  to exit the thread loop and to terminate the thread.
+     */
+    virtual bool inWorkerThread();
+
+    /* Encapsulates a worker thread used by the emulated camera device.
+     */
+    friend class WorkerThread;
+    class WorkerThread : public Thread {
+
+        /****************************************************************************
+         * Public API
+         ***************************************************************************/
+
+        public:
+            inline explicit WorkerThread(EmulatedCameraDevice* camera_dev)
+                : Thread(true),   // Callbacks may involve Java calls.
+                  mCameraDevice(camera_dev),
+                  mThreadControl(-1),
+                  mControlFD(-1)
+            {
+            }
+
+            inline ~WorkerThread()
+            {
+                ALOGW_IF(mThreadControl >= 0 || mControlFD >= 0,
+                        "%s: Control FDs are opened in the destructor",
+                        __FUNCTION__);
+                if (mThreadControl >= 0) {
+                    close(mThreadControl);
+                }
+                if (mControlFD >= 0) {
+                    close(mControlFD);
+                }
+            }
+
+            /* Starts the thread
+             * Param:
+             *  one_burst - Controls how many times thread loop should run. If
+             *      this parameter is 'true', thread routine will run only once
+             *      If this parameter is 'false', thread routine will run until
+             *      stopThread method is called. See startWorkerThread for more
+             *      info.
+             * Return:
+             *  NO_ERROR on success, or an appropriate error status.
+             */
+            inline status_t startThread(bool one_burst)
+            {
+                mOneBurst = one_burst;
+                return run(NULL, ANDROID_PRIORITY_URGENT_DISPLAY, 0);
+            }
+
+            /* Overriden base class method.
+             * It is overriden in order to provide one-time initialization just
+             * prior to starting the thread routine.
+             */
+            status_t readyToRun();
+
+            /* Stops the thread. */
+            status_t stopThread();
+
+            /* Values returned from the Select method of this class. */
+            enum SelectRes {
+                /* A timeout has occurred. */
+                TIMEOUT,
+                /* Data are available for read on the provided FD. */
+                READY,
+                /* Thread exit request has been received. */
+                EXIT_THREAD,
+                /* An error has occurred. */
+                ERROR
+            };
+
+            /* Select on an FD event, keeping in mind thread exit message.
+             * Param:
+             *  fd - File descriptor on which to wait for an event. This
+             *      parameter may be negative. If it is negative this method will
+             *      only wait on a control message to the thread.
+             *  timeout - Timeout in microseconds. 0 indicates no timeout (wait
+             *      forever).
+             * Return:
+             *  See SelectRes enum comments.
+             */
+            SelectRes Select(int fd, int timeout);
+
+        /****************************************************************************
+         * Private API
+         ***************************************************************************/
+
+        private:
+            /* Implements abstract method of the base Thread class. */
+            bool threadLoop()
+            {
+                /* Simply dispatch the call to the containing camera device. */
+                if (mCameraDevice->inWorkerThread()) {
+                    /* Respect "one burst" parameter (see startThread). */
+                    return !mOneBurst;
+                } else {
+                    return false;
+                }
+            }
+
+            /* Containing camera device object. */
+            EmulatedCameraDevice*   mCameraDevice;
+
+            /* FD that is used to send control messages into the thread. */
+            int                     mThreadControl;
+
+            /* FD that thread uses to receive control messages. */
+            int                     mControlFD;
+
+            /* Controls number of times the thread loop runs.
+             * See startThread for more information. */
+            bool                    mOneBurst;
+
+            /* Enumerates control messages that can be sent into the thread. */
+            enum ControlMessage {
+                /* Stop the thread. */
+                THREAD_STOP
+            };
+    };
+
+    /* Worker thread accessor. */
+    inline WorkerThread* getWorkerThread() const
+    {
+        return mWorkerThread.get();
+    }
+
+    /****************************************************************************
+     * Data members
+     ***************************************************************************/
+
+protected:
+    /* Locks this instance for parameters, state, etc. change. */
+    Mutex                       mObjectLock;
+
+    /* Worker thread that is used in frame capturing. */
+    sp<WorkerThread>            mWorkerThread;
+
+    /* Timestamp of the current frame. */
+    nsecs_t                     mCurFrameTimestamp;
+
+    /* Emulated camera object containing this instance. */
+    EmulatedCamera*             mCameraHAL;
+
+    /* Framebuffer containing the current frame. */
+    uint8_t*                    mCurrentFrame;
+
+    /*
+     * Framebuffer properties.
+     */
+
+    /* Byte size of the framebuffer. */
+    size_t                      mFrameBufferSize;
+
+    /* Original pixel format (one of the V4L2_PIX_FMT_XXX values, as defined in
+     * bionic/libc/kernel/common/linux/videodev2.h */
+    uint32_t                    mPixelFormat;
+
+    /* Frame width */
+    int                         mFrameWidth;
+
+    /* Frame height */
+    int                         mFrameHeight;
+
+    /* Total number of pixels */
+    int                         mTotalPixels;
+
+    /* Exposure compensation value */
+    float                       mExposureCompensation;
+
+    float*                      mWhiteBalanceScale;
+
+    DefaultKeyedVector<String8, float*>      mSupportedWhiteBalanceScale;
+
+    /* Defines possible states of the emulated camera device object.
+     */
+    enum EmulatedCameraDeviceState {
+        /* Object has been constructed. */
+        ECDS_CONSTRUCTED,
+        /* Object has been initialized. */
+        ECDS_INITIALIZED,
+        /* Object has been connected to the physical device. */
+        ECDS_CONNECTED,
+        /* Camera device has been started. */
+        ECDS_STARTED,
+    };
+
+    /* Object state. */
+    EmulatedCameraDeviceState   mState;
+};
+
+}; /* namespace android */
+
+#endif  /* HW_EMULATOR_CAMERA_EMULATED_CAMERA_DEVICE_H */
diff --git a/camera/EmulatedCameraFactory.cpp b/camera/EmulatedCameraFactory.cpp
new file mode 100755
index 0000000..0964335
--- /dev/null
+++ b/camera/EmulatedCameraFactory.cpp
@@ -0,0 +1,449 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+/*
+ * Contains implementation of a class EmulatedCameraFactory that manages cameras
+ * available for emulation.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "EmulatedCamera_Factory"
+#include <cutils/log.h>
+#include <cutils/properties.h>
+#include "EmulatedQemuCamera.h"
+#include "EmulatedFakeCamera.h"
+#include "EmulatedFakeCamera2.h"
+#include "EmulatedCameraFactory.h"
+
+extern camera_module_t HAL_MODULE_INFO_SYM;
+
+/* A global instance of EmulatedCameraFactory is statically instantiated and
+ * initialized when camera emulation HAL is loaded.
+ */
+android::EmulatedCameraFactory  gEmulatedCameraFactory;
+
+namespace android {
+
+EmulatedCameraFactory::EmulatedCameraFactory()
+        : mQemuClient(),
+          mEmulatedCameras(NULL),
+          mEmulatedCameraNum(0),
+          mFakeCameraNum(0),
+          mConstructedOK(false)
+{
+    status_t res;
+    /* Connect to the factory service in the emulator, and create Qemu cameras. */
+    if (mQemuClient.connectClient(NULL) == NO_ERROR) {
+        /* Connection has succeeded. Create emulated cameras for each camera
+         * device, reported by the service. */
+        createQemuCameras();
+    }
+
+    if (isBackFakeCameraEmulationOn()) {
+        /* Camera ID. */
+        const int camera_id = mEmulatedCameraNum;
+        /* Use fake camera to emulate back-facing camera. */
+        mEmulatedCameraNum++;
+
+        /* Make sure that array is allocated (in case there were no 'qemu'
+         * cameras created. Note that we preallocate the array so it may contain
+         * two fake cameras: one facing back, and another facing front. */
+        if (mEmulatedCameras == NULL) {
+            mEmulatedCameras = new EmulatedBaseCamera*[mEmulatedCameraNum + 1];
+            if (mEmulatedCameras == NULL) {
+                ALOGE("%s: Unable to allocate emulated camera array for %d entries",
+                     __FUNCTION__, mEmulatedCameraNum);
+                return;
+            }
+            memset(mEmulatedCameras, 0,
+                    (mEmulatedCameraNum + 1) * sizeof(EmulatedBaseCamera*));
+        }
+
+        /* Create, and initialize the fake camera */
+        switch (getBackCameraHalVersion()) {
+            case 1:
+                mEmulatedCameras[camera_id] =
+                        new EmulatedFakeCamera(camera_id, true,
+                                &HAL_MODULE_INFO_SYM.common);
+                break;
+            case 2:
+                mEmulatedCameras[camera_id] =
+                        new EmulatedFakeCamera2(camera_id, true,
+                                &HAL_MODULE_INFO_SYM.common);
+                break;
+            default:
+                ALOGE("%s: Unknown back camera hal version requested: %d", __FUNCTION__,
+                        getBackCameraHalVersion());
+        }
+        if (mEmulatedCameras[camera_id] != NULL) {
+            ALOGV("%s: Back camera device version is %d", __FUNCTION__,
+                    getBackCameraHalVersion());
+            res = mEmulatedCameras[camera_id]->Initialize();
+            if (res != NO_ERROR) {
+                ALOGE("%s: Unable to intialize back camera %d: %s (%d)",
+                        __FUNCTION__, camera_id, strerror(-res), res);
+                delete mEmulatedCameras[camera_id];
+                mEmulatedCameraNum--;
+            }
+        } else {
+            mEmulatedCameraNum--;
+            ALOGE("%s: Unable to instantiate fake camera class", __FUNCTION__);
+        }
+    }
+
+    if (isFrontFakeCameraEmulationOn()) {
+        /* Camera ID. */
+        const int camera_id = mEmulatedCameraNum;
+        /* Use fake camera to emulate front-facing camera. */
+        mEmulatedCameraNum++;
+
+        /* Make sure that array is allocated (in case there were no 'qemu'
+         * cameras created. */
+        if (mEmulatedCameras == NULL) {
+            mEmulatedCameras = new EmulatedBaseCamera*[mEmulatedCameraNum];
+            if (mEmulatedCameras == NULL) {
+                ALOGE("%s: Unable to allocate emulated camera array for %d entries",
+                     __FUNCTION__, mEmulatedCameraNum);
+                return;
+            }
+            memset(mEmulatedCameras, 0,
+                    mEmulatedCameraNum * sizeof(EmulatedBaseCamera*));
+        }
+
+        /* Create, and initialize the fake camera */
+        switch (getFrontCameraHalVersion()) {
+            case 1:
+                mEmulatedCameras[camera_id] =
+                        new EmulatedFakeCamera(camera_id, false,
+                                &HAL_MODULE_INFO_SYM.common);
+                break;
+            case 2:
+                mEmulatedCameras[camera_id] =
+                        new EmulatedFakeCamera2(camera_id, false,
+                                &HAL_MODULE_INFO_SYM.common);
+                break;
+            default:
+                ALOGE("%s: Unknown front camera hal version requested: %d",
+                        __FUNCTION__,
+                        getFrontCameraHalVersion());
+        }
+        if (mEmulatedCameras[camera_id] != NULL) {
+            ALOGV("%s: Front camera device version is %d", __FUNCTION__,
+                    getFrontCameraHalVersion());
+            res = mEmulatedCameras[camera_id]->Initialize();
+            if (res != NO_ERROR) {
+                ALOGE("%s: Unable to intialize front camera %d: %s (%d)",
+                        __FUNCTION__, camera_id, strerror(-res), res);
+                delete mEmulatedCameras[camera_id];
+                mEmulatedCameraNum--;
+            }
+        } else {
+            mEmulatedCameraNum--;
+            ALOGE("%s: Unable to instantiate fake camera class", __FUNCTION__);
+        }
+    }
+
+    ALOGV("%d cameras are being emulated. %d of them are fake cameras.",
+          mEmulatedCameraNum, mFakeCameraNum);
+
+    mConstructedOK = true;
+}
+
+EmulatedCameraFactory::~EmulatedCameraFactory()
+{
+    if (mEmulatedCameras != NULL) {
+        for (int n = 0; n < mEmulatedCameraNum; n++) {
+            if (mEmulatedCameras[n] != NULL) {
+                delete mEmulatedCameras[n];
+            }
+        }
+        delete[] mEmulatedCameras;
+    }
+}
+
+/****************************************************************************
+ * Camera HAL API handlers.
+ *
+ * Each handler simply verifies existence of an appropriate EmulatedBaseCamera
+ * instance, and dispatches the call to that instance.
+ *
+ ***************************************************************************/
+
+int EmulatedCameraFactory::cameraDeviceOpen(int camera_id, hw_device_t** device)
+{
+    ALOGV("%s: id = %d", __FUNCTION__, camera_id);
+
+    *device = NULL;
+
+    if (!isConstructedOK()) {
+        ALOGE("%s: EmulatedCameraFactory has failed to initialize", __FUNCTION__);
+        return -EINVAL;
+    }
+
+    if (camera_id < 0 || camera_id >= getEmulatedCameraNum()) {
+        ALOGE("%s: Camera id %d is out of bounds (%d)",
+             __FUNCTION__, camera_id, getEmulatedCameraNum());
+        return -ENODEV;
+    }
+
+    return mEmulatedCameras[camera_id]->connectCamera(device);
+}
+
+int EmulatedCameraFactory::getCameraInfo(int camera_id, struct camera_info* info)
+{
+    ALOGV("%s: id = %d", __FUNCTION__, camera_id);
+
+    if (!isConstructedOK()) {
+        ALOGE("%s: EmulatedCameraFactory has failed to initialize", __FUNCTION__);
+        return -EINVAL;
+    }
+
+    if (camera_id < 0 || camera_id >= getEmulatedCameraNum()) {
+        ALOGE("%s: Camera id %d is out of bounds (%d)",
+             __FUNCTION__, camera_id, getEmulatedCameraNum());
+        return -ENODEV;
+    }
+
+    return mEmulatedCameras[camera_id]->getCameraInfo(info);
+}
+
+/****************************************************************************
+ * Camera HAL API callbacks.
+ ***************************************************************************/
+
+int EmulatedCameraFactory::device_open(const hw_module_t* module,
+                                       const char* name,
+                                       hw_device_t** device)
+{
+    /*
+     * Simply verify the parameters, and dispatch the call inside the
+     * EmulatedCameraFactory instance.
+     */
+
+    if (module != &HAL_MODULE_INFO_SYM.common) {
+        ALOGE("%s: Invalid module %p expected %p",
+             __FUNCTION__, module, &HAL_MODULE_INFO_SYM.common);
+        return -EINVAL;
+    }
+    if (name == NULL) {
+        ALOGE("%s: NULL name is not expected here", __FUNCTION__);
+        return -EINVAL;
+    }
+
+    return gEmulatedCameraFactory.cameraDeviceOpen(atoi(name), device);
+}
+
+int EmulatedCameraFactory::get_number_of_cameras(void)
+{
+    return gEmulatedCameraFactory.getEmulatedCameraNum();
+}
+
+int EmulatedCameraFactory::get_camera_info(int camera_id,
+                                           struct camera_info* info)
+{
+    return gEmulatedCameraFactory.getCameraInfo(camera_id, info);
+}
+
+/********************************************************************************
+ * Internal API
+ *******************************************************************************/
+
+/*
+ * Camera information tokens passed in response to the "list" factory query.
+ */
+
+/* Device name token. */
+static const char lListNameToken[]    = "name=";
+/* Frame dimensions token. */
+static const char lListDimsToken[]    = "framedims=";
+/* Facing direction token. */
+static const char lListDirToken[]     = "dir=";
+
+void EmulatedCameraFactory::createQemuCameras()
+{
+    /* Obtain camera list. */
+    char* camera_list = NULL;
+    status_t res = mQemuClient.listCameras(&camera_list);
+    /* Empty list, or list containing just an EOL means that there were no
+     * connected cameras found. */
+    if (res != NO_ERROR || camera_list == NULL || *camera_list == '\0' ||
+        *camera_list == '\n') {
+        if (camera_list != NULL) {
+            free(camera_list);
+        }
+        return;
+    }
+
+    /*
+     * Calculate number of connected cameras. Number of EOLs in the camera list
+     * is the number of the connected cameras.
+     */
+
+    int num = 0;
+    const char* eol = strchr(camera_list, '\n');
+    while (eol != NULL) {
+        num++;
+        eol = strchr(eol + 1, '\n');
+    }
+
+    /* Allocate the array for emulated camera instances. Note that we allocate
+     * two more entries for back and front fake camera emulation. */
+    mEmulatedCameras = new EmulatedBaseCamera*[num + 2];
+    if (mEmulatedCameras == NULL) {
+        ALOGE("%s: Unable to allocate emulated camera array for %d entries",
+             __FUNCTION__, num + 1);
+        free(camera_list);
+        return;
+    }
+    memset(mEmulatedCameras, 0, sizeof(EmulatedBaseCamera*) * (num + 1));
+
+    /*
+     * Iterate the list, creating, and initializin emulated qemu cameras for each
+     * entry (line) in the list.
+     */
+
+    int index = 0;
+    char* cur_entry = camera_list;
+    while (cur_entry != NULL && *cur_entry != '\0' && index < num) {
+        /* Find the end of the current camera entry, and terminate it with zero
+         * for simpler string manipulation. */
+        char* next_entry = strchr(cur_entry, '\n');
+        if (next_entry != NULL) {
+            *next_entry = '\0';
+            next_entry++;   // Start of the next entry.
+        }
+
+        /* Find 'name', 'framedims', and 'dir' tokens that are required here. */
+        char* name_start = strstr(cur_entry, lListNameToken);
+        char* dim_start = strstr(cur_entry, lListDimsToken);
+        char* dir_start = strstr(cur_entry, lListDirToken);
+        if (name_start != NULL && dim_start != NULL && dir_start != NULL) {
+            /* Advance to the token values. */
+            name_start += strlen(lListNameToken);
+            dim_start += strlen(lListDimsToken);
+            dir_start += strlen(lListDirToken);
+
+            /* Terminate token values with zero. */
+            char* s = strchr(name_start, ' ');
+            if (s != NULL) {
+                *s = '\0';
+            }
+            s = strchr(dim_start, ' ');
+            if (s != NULL) {
+                *s = '\0';
+            }
+            s = strchr(dir_start, ' ');
+            if (s != NULL) {
+                *s = '\0';
+            }
+
+            /* Create and initialize qemu camera. */
+            EmulatedQemuCamera* qemu_cam =
+                new EmulatedQemuCamera(index, &HAL_MODULE_INFO_SYM.common);
+            if (NULL != qemu_cam) {
+                res = qemu_cam->Initialize(name_start, dim_start, dir_start);
+                if (res == NO_ERROR) {
+                    mEmulatedCameras[index] = qemu_cam;
+                    index++;
+                } else {
+                    delete qemu_cam;
+                }
+            } else {
+                ALOGE("%s: Unable to instantiate EmulatedQemuCamera",
+                     __FUNCTION__);
+            }
+        } else {
+            ALOGW("%s: Bad camera information: %s", __FUNCTION__, cur_entry);
+        }
+
+        cur_entry = next_entry;
+    }
+
+    mEmulatedCameraNum = index;
+}
+
+bool EmulatedCameraFactory::isBackFakeCameraEmulationOn()
+{
+    /* Defined by 'qemu.sf.fake_camera' boot property: if property exist, and
+     * is set to 'both', or 'back', then fake camera is used to emulate back
+     * camera. */
+    char prop[PROPERTY_VALUE_MAX];
+    if ((property_get("qemu.sf.fake_camera", prop, NULL) > 0) &&
+        (!strcmp(prop, "both") || !strcmp(prop, "back"))) {
+        return true;
+    } else {
+        return false;
+    }
+}
+
+int EmulatedCameraFactory::getBackCameraHalVersion()
+{
+    /* Defined by 'qemu.sf.back_camera_hal_version' boot property: if the
+     * property doesn't exist, it is assumed to be 1. */
+    char prop[PROPERTY_VALUE_MAX];
+    if (property_get("qemu.sf.back_camera_hal", prop, NULL) > 0) {
+        char *prop_end = prop;
+        int val = strtol(prop, &prop_end, 10);
+        if (*prop_end == '\0') {
+            return val;
+        }
+        // Badly formatted property, should just be a number
+        ALOGE("qemu.sf.back_camera_hal is not a number: %s", prop);
+    }
+    return 1;
+}
+
+bool EmulatedCameraFactory::isFrontFakeCameraEmulationOn()
+{
+    /* Defined by 'qemu.sf.fake_camera' boot property: if property exist, and
+     * is set to 'both', or 'front', then fake camera is used to emulate front
+     * camera. */
+    char prop[PROPERTY_VALUE_MAX];
+    if ((property_get("qemu.sf.fake_camera", prop, NULL) > 0) &&
+        (!strcmp(prop, "both") || !strcmp(prop, "front"))) {
+        return true;
+    } else {
+        return false;
+    }
+}
+
+int EmulatedCameraFactory::getFrontCameraHalVersion()
+{
+    /* Defined by 'qemu.sf.front_camera_hal_version' boot property: if the
+     * property doesn't exist, it is assumed to be 1. */
+    char prop[PROPERTY_VALUE_MAX];
+    if (property_get("qemu.sf.front_camera_hal", prop, NULL) > 0) {
+        char *prop_end = prop;
+        int val = strtol(prop, &prop_end, 10);
+        if (*prop_end == '\0') {
+            return val;
+        }
+        // Badly formatted property, should just be a number
+        ALOGE("qemu.sf.front_camera_hal is not a number: %s", prop);
+    }
+    return 1;
+}
+
+/********************************************************************************
+ * Initializer for the static member structure.
+ *******************************************************************************/
+
+/* Entry point for camera HAL API. */
+struct hw_module_methods_t EmulatedCameraFactory::mCameraModuleMethods = {
+    open: EmulatedCameraFactory::device_open
+};
+
+}; /* namespace android */
diff --git a/camera/EmulatedCameraFactory.h b/camera/EmulatedCameraFactory.h
new file mode 100755
index 0000000..123e735
--- /dev/null
+++ b/camera/EmulatedCameraFactory.h
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef HW_EMULATOR_CAMERA_EMULATED_CAMERA_FACTORY_H
+#define HW_EMULATOR_CAMERA_EMULATED_CAMERA_FACTORY_H
+
+#include "EmulatedBaseCamera.h"
+#include "QemuClient.h"
+
+namespace android {
+
+/*
+ * Contains declaration of a class EmulatedCameraFactory that manages cameras
+ * available for the emulation. A global instance of this class is statically
+ * instantiated and initialized when camera emulation HAL is loaded.
+ */
+
+/* Class EmulatedCameraFactoryManages cameras available for the emulation.
+ *
+ * When the global static instance of this class is created on the module load,
+ * it enumerates cameras available for the emulation by connecting to the
+ * emulator's 'camera' service. For every camera found out there it creates an
+ * instance of an appropriate class, and stores it an in array of emulated
+ * cameras. In addition to the cameras reported by the emulator, a fake camera
+ * emulator is always created, so there is always at least one camera that is
+ * available.
+ *
+ * Instance of this class is also used as the entry point for the camera HAL API,
+ * including:
+ *  - hw_module_methods_t::open entry point
+ *  - camera_module_t::get_number_of_cameras entry point
+ *  - camera_module_t::get_camera_info entry point
+ *
+ */
+class EmulatedCameraFactory {
+public:
+    /* Constructs EmulatedCameraFactory instance.
+     * In this constructor the factory will create and initialize a list of
+     * emulated cameras. All errors that occur on this constructor are reported
+     * via mConstructedOK data member of this class.
+     */
+    EmulatedCameraFactory();
+
+    /* Destructs EmulatedCameraFactory instance. */
+    ~EmulatedCameraFactory();
+
+    /****************************************************************************
+     * Camera HAL API handlers.
+     ***************************************************************************/
+
+public:
+    /* Opens (connects to) a camera device.
+     * This method is called in response to hw_module_methods_t::open callback.
+     */
+    int cameraDeviceOpen(int camera_id, hw_device_t** device);
+
+    /* Gets emulated camera information.
+     * This method is called in response to camera_module_t::get_camera_info callback.
+     */
+    int getCameraInfo(int camera_id, struct camera_info *info);
+
+    /****************************************************************************
+     * Camera HAL API callbacks.
+     ***************************************************************************/
+
+public:
+    /* camera_module_t::get_number_of_cameras callback entry point. */
+    static int get_number_of_cameras(void);
+
+    /* camera_module_t::get_camera_info callback entry point. */
+    static int get_camera_info(int camera_id, struct camera_info *info);
+
+private:
+    /* hw_module_methods_t::open callback entry point. */
+    static int device_open(const hw_module_t* module,
+                           const char* name,
+                           hw_device_t** device);
+
+    /****************************************************************************
+     * Public API.
+     ***************************************************************************/
+
+public:
+
+    /* Gets fake camera orientation. */
+    int getFakeCameraOrientation() {
+        /* TODO: Have a boot property that controls that. */
+        return 90;
+    }
+
+    /* Gets qemu camera orientation. */
+    int getQemuCameraOrientation() {
+        /* TODO: Have a boot property that controls that. */
+        return 270;
+    }
+
+    /* Gets number of emulated cameras.
+     */
+    int getEmulatedCameraNum() const {
+        return mEmulatedCameraNum;
+    }
+
+    /* Checks whether or not the constructor has succeeded.
+     */
+    bool isConstructedOK() const {
+        return mConstructedOK;
+    }
+
+    /****************************************************************************
+     * Private API
+     ***************************************************************************/
+
+private:
+    /* Populates emulated cameras array with cameras that are available via
+     * 'camera' service in the emulator. For each such camera and instance of
+     * the EmulatedCameraQemud will be created and added to the mEmulatedCameras
+     * array.
+     */
+    void createQemuCameras();
+
+    /* Checks if fake camera emulation is on for the camera facing back. */
+    bool isBackFakeCameraEmulationOn();
+
+    /* Gets camera device version number to use for back camera emulation */
+    int getBackCameraHalVersion();
+
+    /* Checks if fake camera emulation is on for the camera facing front. */
+    bool isFrontFakeCameraEmulationOn();
+
+    /* Gets camera device version number to use for front camera emulation */
+    int getFrontCameraHalVersion();
+
+    /****************************************************************************
+     * Data members.
+     ***************************************************************************/
+
+private:
+    /* Connection to the camera service in the emulator. */
+    FactoryQemuClient   mQemuClient;
+
+    /* Array of cameras available for the emulation. */
+    EmulatedBaseCamera**    mEmulatedCameras;
+
+    /* Number of emulated cameras (including the fake ones). */
+    int                 mEmulatedCameraNum;
+
+    /* Number of emulated fake cameras. */
+    int                 mFakeCameraNum;
+
+    /* Flags whether or not constructor has succeeded. */
+    bool                mConstructedOK;
+
+public:
+    /* Contains device open entry point, as required by HAL API. */
+    static struct hw_module_methods_t   mCameraModuleMethods;
+};
+
+}; /* namespace android */
+
+/* References the global EmulatedCameraFactory instance. */
+extern android::EmulatedCameraFactory   gEmulatedCameraFactory;
+
+#endif  /* HW_EMULATOR_CAMERA_EMULATED_CAMERA_FACTORY_H */
diff --git a/camera/EmulatedCameraHal.cpp b/camera/EmulatedCameraHal.cpp
new file mode 100755
index 0000000..aa0cb00
--- /dev/null
+++ b/camera/EmulatedCameraHal.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+/*
+ * Contains implementation of the camera HAL layer in the system running
+ * under the emulator.
+ *
+ * This file contains only required HAL header, which directs all the API calls
+ * to the EmulatedCameraFactory class implementation, wich is responsible for
+ * managing emulated cameras.
+ */
+
+#include "EmulatedCameraFactory.h"
+
+/*
+ * Required HAL header.
+ */
+camera_module_t HAL_MODULE_INFO_SYM = {
+    common: {
+         tag:                HARDWARE_MODULE_TAG,
+         module_api_version: CAMERA_MODULE_API_VERSION_2_0,
+         hal_api_version:    HARDWARE_HAL_API_VERSION,
+         id:                 CAMERA_HARDWARE_MODULE_ID,
+         name:               "Emulated Camera Module",
+         author:             "The Android Open Source Project",
+         methods:            &android::EmulatedCameraFactory::mCameraModuleMethods,
+         dso:                NULL,
+         reserved:           {0},
+    },
+    get_number_of_cameras:  android::EmulatedCameraFactory::get_number_of_cameras,
+    get_camera_info:        android::EmulatedCameraFactory::get_camera_info,
+};
diff --git a/camera/EmulatedFakeCamera.cpp b/camera/EmulatedFakeCamera.cpp
new file mode 100755
index 0000000..457850d
--- /dev/null
+++ b/camera/EmulatedFakeCamera.cpp
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+/*
+ * Contains implementation of a class EmulatedFakeCamera that encapsulates
+ * functionality of a fake camera.
+ */
+
+#define LOG_NDEBUG 0
+#define LOG_TAG "EmulatedCamera_FakeCamera"
+#include <cutils/log.h>
+#include <cutils/properties.h>
+#include "EmulatedFakeCamera.h"
+#include "EmulatedCameraFactory.h"
+
+namespace android {
+
+EmulatedFakeCamera::EmulatedFakeCamera(int cameraId,
+                                       bool facingBack,
+                                       struct hw_module_t* module)
+        : EmulatedCamera(cameraId, module),
+          mFacingBack(facingBack),
+          mFakeCameraDevice(this)
+{
+}
+
+EmulatedFakeCamera::~EmulatedFakeCamera()
+{
+}
+
+/****************************************************************************
+ * Public API overrides
+ ***************************************************************************/
+
+status_t EmulatedFakeCamera::Initialize()
+{
+    status_t res = mFakeCameraDevice.Initialize();
+    if (res != NO_ERROR) {
+        return res;
+    }
+
+    const char* facing = mFacingBack ? EmulatedCamera::FACING_BACK :
+                                       EmulatedCamera::FACING_FRONT;
+
+    mParameters.set(EmulatedCamera::FACING_KEY, facing);
+    ALOGD("%s: Fake camera is facing %s", __FUNCTION__, facing);
+
+    mParameters.set(EmulatedCamera::ORIENTATION_KEY,
+                    gEmulatedCameraFactory.getFakeCameraOrientation());
+
+    res = EmulatedCamera::Initialize();
+    if (res != NO_ERROR) {
+        return res;
+    }
+
+    /*
+     * Parameters provided by the camera device.
+     */
+
+    /* 352x288 and 320x240 frame dimensions are required by the framework for
+     * video mode preview and video recording. */
+    mParameters.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
+                    "640x480,352x288,320x240");
+    mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
+                    "640x480,352x288,320x240");
+    mParameters.setPreviewSize(640, 480);
+    mParameters.setPictureSize(640, 480);
+
+    return NO_ERROR;
+}
+
+EmulatedCameraDevice* EmulatedFakeCamera::getCameraDevice()
+{
+    return &mFakeCameraDevice;
+}
+
+};  /* namespace android */
diff --git a/camera/EmulatedFakeCamera.h b/camera/EmulatedFakeCamera.h
new file mode 100755
index 0000000..4bfbd70
--- /dev/null
+++ b/camera/EmulatedFakeCamera.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef HW_EMULATOR_CAMERA_EMULATED_FAKE_CAMERA_H
+#define HW_EMULATOR_CAMERA_EMULATED_FAKE_CAMERA_H
+
+/*
+ * Contains declaration of a class EmulatedFakeCamera that encapsulates
+ * functionality of a fake camera. This class is nothing more than a placeholder
+ * for EmulatedFakeCameraDevice instance.
+ */
+
+#include "EmulatedCamera.h"
+#include "EmulatedFakeCameraDevice.h"
+
+namespace android {
+
+/* Encapsulates functionality of a fake camera.
+ * This class is nothing more than a placeholder for EmulatedFakeCameraDevice
+ * instance that emulates a fake camera device.
+ */
+class EmulatedFakeCamera : public EmulatedCamera {
+public:
+    /* Constructs EmulatedFakeCamera instance. */
+    EmulatedFakeCamera(int cameraId, bool facingBack, struct hw_module_t* module);
+
+    /* Destructs EmulatedFakeCamera instance. */
+    ~EmulatedFakeCamera();
+
+    /****************************************************************************
+     * EmulatedCamera virtual overrides.
+     ***************************************************************************/
+
+public:
+    /* Initializes EmulatedFakeCamera instance. */
+     status_t Initialize();
+
+    /****************************************************************************
+     * EmulatedCamera abstract API implementation.
+     ***************************************************************************/
+
+protected:
+    /* Gets emulated camera device ised by this instance of the emulated camera.
+     */
+    EmulatedCameraDevice* getCameraDevice();
+
+    /****************************************************************************
+     * Data memebers.
+     ***************************************************************************/
+
+protected:
+    /* Facing back (true) or front (false) switch. */
+    bool                        mFacingBack;
+
+    /* Contained fake camera device object. */
+    EmulatedFakeCameraDevice    mFakeCameraDevice;
+};
+
+}; /* namespace android */
+
+#endif  /* HW_EMULATOR_CAMERA_EMULATED_FAKE_CAMERA_H */
diff --git a/camera/EmulatedFakeCamera2.cpp b/camera/EmulatedFakeCamera2.cpp
new file mode 100644
index 0000000..fa5978a
--- /dev/null
+++ b/camera/EmulatedFakeCamera2.cpp
@@ -0,0 +1,2708 @@
+/*
+ * Copyright (C) 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.
+ */
+
+/*
+ * Contains implementation of a class EmulatedFakeCamera2 that encapsulates
+ * functionality of an advanced fake camera.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "EmulatedCamera_FakeCamera2"
+#include <utils/Log.h>
+
+#include "EmulatedFakeCamera2.h"
+#include "EmulatedCameraFactory.h"
+#include <ui/Rect.h>
+#include <ui/GraphicBufferMapper.h>
+#include "gralloc_cb.h"
+
+namespace android {
+
+const int64_t USEC = 1000LL;
+const int64_t MSEC = USEC * 1000LL;
+const int64_t SEC = MSEC * 1000LL;
+
+const uint32_t EmulatedFakeCamera2::kAvailableFormats[4] = {
+        HAL_PIXEL_FORMAT_RAW_SENSOR,
+        HAL_PIXEL_FORMAT_BLOB,
+        HAL_PIXEL_FORMAT_RGBA_8888,
+        //        HAL_PIXEL_FORMAT_YV12,
+        HAL_PIXEL_FORMAT_YCrCb_420_SP
+};
+
+const uint32_t EmulatedFakeCamera2::kAvailableRawSizes[2] = {
+    640, 480
+    //    Sensor::kResolution[0], Sensor::kResolution[1]
+};
+
+const uint64_t EmulatedFakeCamera2::kAvailableRawMinDurations[1] = {
+    Sensor::kFrameDurationRange[0]
+};
+
+const uint32_t EmulatedFakeCamera2::kAvailableProcessedSizesBack[4] = {
+    640, 480, 320, 240
+    //    Sensor::kResolution[0], Sensor::kResolution[1]
+};
+
+const uint32_t EmulatedFakeCamera2::kAvailableProcessedSizesFront[4] = {
+    320, 240, 160, 120
+    //    Sensor::kResolution[0], Sensor::kResolution[1]
+};
+
+const uint64_t EmulatedFakeCamera2::kAvailableProcessedMinDurations[1] = {
+    Sensor::kFrameDurationRange[0]
+};
+
+const uint32_t EmulatedFakeCamera2::kAvailableJpegSizesBack[2] = {
+    640, 480
+    //    Sensor::kResolution[0], Sensor::kResolution[1]
+};
+
+const uint32_t EmulatedFakeCamera2::kAvailableJpegSizesFront[2] = {
+    320, 240
+    //    Sensor::kResolution[0], Sensor::kResolution[1]
+};
+
+
+const uint64_t EmulatedFakeCamera2::kAvailableJpegMinDurations[1] = {
+    Sensor::kFrameDurationRange[0]
+};
+
+
+EmulatedFakeCamera2::EmulatedFakeCamera2(int cameraId,
+        bool facingBack,
+        struct hw_module_t* module)
+        : EmulatedCamera2(cameraId,module),
+          mFacingBack(facingBack)
+{
+    ALOGD("Constructing emulated fake camera 2 facing %s",
+            facingBack ? "back" : "front");
+}
+
+EmulatedFakeCamera2::~EmulatedFakeCamera2() {
+    if (mCameraInfo != NULL) {
+        free_camera_metadata(mCameraInfo);
+    }
+}
+
+/****************************************************************************
+ * Public API overrides
+ ***************************************************************************/
+
+status_t EmulatedFakeCamera2::Initialize() {
+    status_t res;
+
+    set_camera_metadata_vendor_tag_ops(
+            static_cast<vendor_tag_query_ops_t*>(&mVendorTagOps));
+
+    res = constructStaticInfo(&mCameraInfo, true);
+    if (res != OK) {
+        ALOGE("%s: Unable to allocate static info: %s (%d)",
+                __FUNCTION__, strerror(-res), res);
+        return res;
+    }
+    res = constructStaticInfo(&mCameraInfo, false);
+    if (res != OK) {
+        ALOGE("%s: Unable to fill in static info: %s (%d)",
+                __FUNCTION__, strerror(-res), res);
+        return res;
+    }
+    if (res != OK) return res;
+
+    mNextStreamId = 1;
+    mNextReprocessStreamId = 1;
+    mRawStreamCount = 0;
+    mProcessedStreamCount = 0;
+    mJpegStreamCount = 0;
+    mReprocessStreamCount = 0;
+
+    return NO_ERROR;
+}
+
+/****************************************************************************
+ * Camera module API overrides
+ ***************************************************************************/
+
+status_t EmulatedFakeCamera2::connectCamera(hw_device_t** device) {
+    status_t res;
+    ALOGV("%s", __FUNCTION__);
+
+    mConfigureThread = new ConfigureThread(this);
+    mReadoutThread = new ReadoutThread(this);
+    mControlThread = new ControlThread(this);
+    mSensor = new Sensor(this);
+    mJpegCompressor = new JpegCompressor(this);
+
+    mNextStreamId = 1;
+    mNextReprocessStreamId = 1;
+
+    res = mSensor->startUp();
+    if (res != NO_ERROR) return res;
+
+    res = mConfigureThread->run("EmulatedFakeCamera2::configureThread");
+    if (res != NO_ERROR) return res;
+
+    res = mReadoutThread->run("EmulatedFakeCamera2::readoutThread");
+    if (res != NO_ERROR) return res;
+
+    res = mControlThread->run("EmulatedFakeCamera2::controlThread");
+    if (res != NO_ERROR) return res;
+
+    return EmulatedCamera2::connectCamera(device);
+}
+
+status_t EmulatedFakeCamera2::closeCamera() {
+    {
+        Mutex::Autolock l(mMutex);
+
+        status_t res;
+        ALOGV("%s", __FUNCTION__);
+
+        res = mSensor->shutDown();
+        if (res != NO_ERROR) {
+            ALOGE("%s: Unable to shut down sensor: %d", __FUNCTION__, res);
+            return res;
+        }
+
+        mConfigureThread->requestExit();
+        mReadoutThread->requestExit();
+        mControlThread->requestExit();
+        mJpegCompressor->cancel();
+    }
+
+    // give up the lock since we will now block and the threads
+    // can call back into this object
+    mConfigureThread->join();
+    mReadoutThread->join();
+    mControlThread->join();
+
+    ALOGV("%s exit", __FUNCTION__);
+    return NO_ERROR;
+}
+
+status_t EmulatedFakeCamera2::getCameraInfo(struct camera_info *info) {
+    info->facing = mFacingBack ? CAMERA_FACING_BACK : CAMERA_FACING_FRONT;
+    info->orientation = gEmulatedCameraFactory.getFakeCameraOrientation();
+    return EmulatedCamera2::getCameraInfo(info);
+}
+
+/****************************************************************************
+ * Camera device API overrides
+ ***************************************************************************/
+
+/** Request input queue */
+
+int EmulatedFakeCamera2::requestQueueNotify() {
+    ALOGV("Request queue notification received");
+
+    ALOG_ASSERT(mRequestQueueSrc != NULL,
+            "%s: Request queue src not set, but received queue notification!",
+            __FUNCTION__);
+    ALOG_ASSERT(mFrameQueueDst != NULL,
+            "%s: Request queue src not set, but received queue notification!",
+            __FUNCTION__);
+    ALOG_ASSERT(mStreams.size() != 0,
+            "%s: No streams allocated, but received queue notification!",
+            __FUNCTION__);
+    return mConfigureThread->newRequestAvailable();
+}
+
+int EmulatedFakeCamera2::getInProgressCount() {
+    Mutex::Autolock l(mMutex);
+
+    int requestCount = 0;
+    requestCount += mConfigureThread->getInProgressCount();
+    requestCount += mReadoutThread->getInProgressCount();
+    requestCount += mJpegCompressor->isBusy() ? 1 : 0;
+
+    return requestCount;
+}
+
+int EmulatedFakeCamera2::constructDefaultRequest(
+        int request_template,
+        camera_metadata_t **request) {
+
+    if (request == NULL) return BAD_VALUE;
+    if (request_template < 0 || request_template >= CAMERA2_TEMPLATE_COUNT) {
+        return BAD_VALUE;
+    }
+    status_t res;
+    // Pass 1, calculate size and allocate
+    res = constructDefaultRequest(request_template,
+            request,
+            true);
+    if (res != OK) {
+        return res;
+    }
+    // Pass 2, build request
+    res = constructDefaultRequest(request_template,
+            request,
+            false);
+    if (res != OK) {
+        ALOGE("Unable to populate new request for template %d",
+                request_template);
+    }
+
+    return res;
+}
+
+int EmulatedFakeCamera2::allocateStream(
+        uint32_t width,
+        uint32_t height,
+        int format,
+        const camera2_stream_ops_t *stream_ops,
+        uint32_t *stream_id,
+        uint32_t *format_actual,
+        uint32_t *usage,
+        uint32_t *max_buffers) {
+    Mutex::Autolock l(mMutex);
+
+    // Temporary shim until FORMAT_ZSL is removed
+    if (format == CAMERA2_HAL_PIXEL_FORMAT_ZSL) {
+        format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
+    }
+
+    if (format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
+        unsigned int numFormats = sizeof(kAvailableFormats) / sizeof(uint32_t);
+        unsigned int formatIdx = 0;
+        unsigned int sizeOffsetIdx = 0;
+        for (; formatIdx < numFormats; formatIdx++) {
+            if (format == (int)kAvailableFormats[formatIdx]) break;
+        }
+        if (formatIdx == numFormats) {
+            ALOGE("%s: Format 0x%x is not supported", __FUNCTION__, format);
+            return BAD_VALUE;
+        }
+    }
+
+    const uint32_t *availableSizes;
+    size_t availableSizeCount;
+    switch (format) {
+        case HAL_PIXEL_FORMAT_RAW_SENSOR:
+            availableSizes = kAvailableRawSizes;
+            availableSizeCount = sizeof(kAvailableRawSizes)/sizeof(uint32_t);
+            break;
+        case HAL_PIXEL_FORMAT_BLOB:
+            availableSizes = mFacingBack ?
+                    kAvailableJpegSizesBack : kAvailableJpegSizesFront;
+            availableSizeCount = mFacingBack ?
+                    sizeof(kAvailableJpegSizesBack)/sizeof(uint32_t) :
+                    sizeof(kAvailableJpegSizesFront)/sizeof(uint32_t);
+            break;
+        case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
+        case HAL_PIXEL_FORMAT_RGBA_8888:
+        case HAL_PIXEL_FORMAT_YV12:
+        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+            availableSizes = mFacingBack ?
+                    kAvailableProcessedSizesBack : kAvailableProcessedSizesFront;
+            availableSizeCount = mFacingBack ?
+                    sizeof(kAvailableProcessedSizesBack)/sizeof(uint32_t) :
+                    sizeof(kAvailableProcessedSizesFront)/sizeof(uint32_t);
+            break;
+        default:
+            ALOGE("%s: Unknown format 0x%x", __FUNCTION__, format);
+            return BAD_VALUE;
+    }
+
+    unsigned int resIdx = 0;
+    for (; resIdx < availableSizeCount; resIdx++) {
+        if (availableSizes[resIdx * 2] == width &&
+                availableSizes[resIdx * 2 + 1] == height) break;
+    }
+    if (resIdx == availableSizeCount) {
+        ALOGE("%s: Format 0x%x does not support resolution %d, %d", __FUNCTION__,
+                format, width, height);
+        return BAD_VALUE;
+    }
+
+    switch (format) {
+        case HAL_PIXEL_FORMAT_RAW_SENSOR:
+            if (mRawStreamCount >= kMaxRawStreamCount) {
+                ALOGE("%s: Cannot allocate another raw stream (%d already allocated)",
+                        __FUNCTION__, mRawStreamCount);
+                return INVALID_OPERATION;
+            }
+            mRawStreamCount++;
+            break;
+        case HAL_PIXEL_FORMAT_BLOB:
+            if (mJpegStreamCount >= kMaxJpegStreamCount) {
+                ALOGE("%s: Cannot allocate another JPEG stream (%d already allocated)",
+                        __FUNCTION__, mJpegStreamCount);
+                return INVALID_OPERATION;
+            }
+            mJpegStreamCount++;
+            break;
+        default:
+            if (mProcessedStreamCount >= kMaxProcessedStreamCount) {
+                ALOGE("%s: Cannot allocate another processed stream (%d already allocated)",
+                        __FUNCTION__, mProcessedStreamCount);
+                return INVALID_OPERATION;
+            }
+            mProcessedStreamCount++;
+    }
+
+    Stream newStream;
+    newStream.ops = stream_ops;
+    newStream.width = width;
+    newStream.height = height;
+    newStream.format = format;
+    // TODO: Query stride from gralloc
+    newStream.stride = width;
+
+    mStreams.add(mNextStreamId, newStream);
+
+    *stream_id = mNextStreamId;
+    if (format_actual) *format_actual = format;
+    *usage = GRALLOC_USAGE_HW_CAMERA_WRITE;
+    *max_buffers = kMaxBufferCount;
+
+    ALOGV("Stream allocated: %d, %d x %d, 0x%x. U: %x, B: %d",
+            *stream_id, width, height, format, *usage, *max_buffers);
+
+    mNextStreamId++;
+    return NO_ERROR;
+}
+
+int EmulatedFakeCamera2::registerStreamBuffers(
+            uint32_t stream_id,
+            int num_buffers,
+            buffer_handle_t *buffers) {
+    Mutex::Autolock l(mMutex);
+
+    ALOGV("%s: Stream %d registering %d buffers", __FUNCTION__,
+            stream_id, num_buffers);
+    // Need to find out what the final concrete pixel format for our stream is
+    // Assumes that all buffers have the same format.
+    if (num_buffers < 1) {
+        ALOGE("%s: Stream %d only has %d buffers!",
+                __FUNCTION__, stream_id, num_buffers);
+        return BAD_VALUE;
+    }
+    const cb_handle_t *streamBuffer =
+            reinterpret_cast<const cb_handle_t*>(buffers[0]);
+
+    int finalFormat = streamBuffer->format;
+
+    if (finalFormat == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
+        ALOGE("%s: Stream %d: Bad final pixel format "
+                "HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED; "
+                "concrete pixel format required!", __FUNCTION__, stream_id);
+        return BAD_VALUE;
+    }
+
+    ssize_t streamIndex = mStreams.indexOfKey(stream_id);
+    if (streamIndex < 0) {
+        ALOGE("%s: Unknown stream id %d!", __FUNCTION__, stream_id);
+        return BAD_VALUE;
+    }
+
+    Stream &stream = mStreams.editValueAt(streamIndex);
+
+    ALOGV("%s: Stream %d format set to %x, previously %x",
+            __FUNCTION__, stream_id, finalFormat, stream.format);
+
+    stream.format = finalFormat;
+
+    return NO_ERROR;
+}
+
+int EmulatedFakeCamera2::releaseStream(uint32_t stream_id) {
+    Mutex::Autolock l(mMutex);
+
+    ssize_t streamIndex = mStreams.indexOfKey(stream_id);
+    if (streamIndex < 0) {
+        ALOGE("%s: Unknown stream id %d!", __FUNCTION__, stream_id);
+        return BAD_VALUE;
+    }
+
+    if (isStreamInUse(stream_id)) {
+        ALOGE("%s: Cannot release stream %d; in use!", __FUNCTION__,
+                stream_id);
+        return BAD_VALUE;
+    }
+
+    switch(mStreams.valueAt(streamIndex).format) {
+        case HAL_PIXEL_FORMAT_RAW_SENSOR:
+            mRawStreamCount--;
+            break;
+        case HAL_PIXEL_FORMAT_BLOB:
+            mJpegStreamCount--;
+            break;
+        default:
+            mProcessedStreamCount--;
+            break;
+    }
+
+    mStreams.removeItemsAt(streamIndex);
+
+    return NO_ERROR;
+}
+
+int EmulatedFakeCamera2::allocateReprocessStreamFromStream(
+        uint32_t output_stream_id,
+        const camera2_stream_in_ops_t *stream_ops,
+        uint32_t *stream_id) {
+    Mutex::Autolock l(mMutex);
+
+    ssize_t baseStreamIndex = mStreams.indexOfKey(output_stream_id);
+    if (baseStreamIndex < 0) {
+        ALOGE("%s: Unknown output stream id %d!", __FUNCTION__, output_stream_id);
+        return BAD_VALUE;
+    }
+
+    const Stream &baseStream = mStreams[baseStreamIndex];
+
+    // We'll reprocess anything we produced
+
+    if (mReprocessStreamCount >= kMaxReprocessStreamCount) {
+        ALOGE("%s: Cannot allocate another reprocess stream (%d already allocated)",
+                __FUNCTION__, mReprocessStreamCount);
+        return INVALID_OPERATION;
+    }
+    mReprocessStreamCount++;
+
+    ReprocessStream newStream;
+    newStream.ops = stream_ops;
+    newStream.width = baseStream.width;
+    newStream.height = baseStream.height;
+    newStream.format = baseStream.format;
+    newStream.stride = baseStream.stride;
+    newStream.sourceStreamId = output_stream_id;
+
+    *stream_id = mNextReprocessStreamId;
+    mReprocessStreams.add(mNextReprocessStreamId, newStream);
+
+    ALOGV("Reprocess stream allocated: %d: %d, %d, 0x%x. Parent stream: %d",
+            *stream_id, newStream.width, newStream.height, newStream.format,
+            output_stream_id);
+
+    mNextReprocessStreamId++;
+    return NO_ERROR;
+}
+
+int EmulatedFakeCamera2::releaseReprocessStream(uint32_t stream_id) {
+    Mutex::Autolock l(mMutex);
+
+    ssize_t streamIndex = mReprocessStreams.indexOfKey(stream_id);
+    if (streamIndex < 0) {
+        ALOGE("%s: Unknown reprocess stream id %d!", __FUNCTION__, stream_id);
+        return BAD_VALUE;
+    }
+
+    if (isReprocessStreamInUse(stream_id)) {
+        ALOGE("%s: Cannot release reprocessing stream %d; in use!", __FUNCTION__,
+                stream_id);
+        return BAD_VALUE;
+    }
+
+    mReprocessStreamCount--;
+    mReprocessStreams.removeItemsAt(streamIndex);
+
+    return NO_ERROR;
+}
+
+int EmulatedFakeCamera2::triggerAction(uint32_t trigger_id,
+        int32_t ext1,
+        int32_t ext2) {
+    Mutex::Autolock l(mMutex);
+    return mControlThread->triggerAction(trigger_id,
+            ext1, ext2);
+}
+
+/** Custom tag definitions */
+
+// Emulator camera metadata sections
+enum {
+    EMULATOR_SCENE = VENDOR_SECTION,
+    END_EMULATOR_SECTIONS
+};
+
+enum {
+    EMULATOR_SCENE_START = EMULATOR_SCENE << 16,
+};
+
+// Emulator camera metadata tags
+enum {
+    // Hour of day to use for lighting calculations (0-23). Default: 12
+    EMULATOR_SCENE_HOUROFDAY = EMULATOR_SCENE_START,
+    EMULATOR_SCENE_END
+};
+
+unsigned int emulator_metadata_section_bounds[END_EMULATOR_SECTIONS -
+        VENDOR_SECTION][2] = {
+    { EMULATOR_SCENE_START, EMULATOR_SCENE_END }
+};
+
+const char *emulator_metadata_section_names[END_EMULATOR_SECTIONS -
+        VENDOR_SECTION] = {
+    "com.android.emulator.scene"
+};
+
+typedef struct emulator_tag_info {
+    const char *tag_name;
+    uint8_t     tag_type;
+} emulator_tag_info_t;
+
+emulator_tag_info_t emulator_scene[EMULATOR_SCENE_END - EMULATOR_SCENE_START] = {
+    { "hourOfDay", TYPE_INT32 }
+};
+
+emulator_tag_info_t *tag_info[END_EMULATOR_SECTIONS -
+        VENDOR_SECTION] = {
+    emulator_scene
+};
+
+const char* EmulatedFakeCamera2::getVendorSectionName(uint32_t tag) {
+    ALOGV("%s", __FUNCTION__);
+    uint32_t section = tag >> 16;
+    if (section < VENDOR_SECTION || section > END_EMULATOR_SECTIONS) return NULL;
+    return emulator_metadata_section_names[section - VENDOR_SECTION];
+}
+
+const char* EmulatedFakeCamera2::getVendorTagName(uint32_t tag) {
+    ALOGV("%s", __FUNCTION__);
+    uint32_t section = tag >> 16;
+    if (section < VENDOR_SECTION || section > END_EMULATOR_SECTIONS) return NULL;
+    uint32_t section_index = section - VENDOR_SECTION;
+    if (tag >= emulator_metadata_section_bounds[section_index][1]) {
+        return NULL;
+    }
+    uint32_t tag_index = tag & 0xFFFF;
+    return tag_info[section_index][tag_index].tag_name;
+}
+
+int EmulatedFakeCamera2::getVendorTagType(uint32_t tag) {
+    ALOGV("%s", __FUNCTION__);
+    uint32_t section = tag >> 16;
+    if (section < VENDOR_SECTION || section > END_EMULATOR_SECTIONS) return -1;
+    uint32_t section_index = section - VENDOR_SECTION;
+    if (tag >= emulator_metadata_section_bounds[section_index][1]) {
+        return -1;
+    }
+    uint32_t tag_index = tag & 0xFFFF;
+    return tag_info[section_index][tag_index].tag_type;
+}
+
+/** Shutdown and debug methods */
+
+int EmulatedFakeCamera2::dump(int fd) {
+    String8 result;
+
+    result.appendFormat("    Camera HAL device: EmulatedFakeCamera2\n");
+    result.appendFormat("      Streams:\n");
+    for (size_t i = 0; i < mStreams.size(); i++) {
+        int id = mStreams.keyAt(i);
+        const Stream& s = mStreams.valueAt(i);
+        result.appendFormat(
+            "         Stream %d: %d x %d, format 0x%x, stride %d\n",
+            id, s.width, s.height, s.format, s.stride);
+    }
+
+    write(fd, result.string(), result.size());
+
+    return NO_ERROR;
+}
+
+void EmulatedFakeCamera2::signalError() {
+    // TODO: Let parent know so we can shut down cleanly
+    ALOGE("Worker thread is signaling a serious error");
+}
+
+/** Pipeline control worker thread methods */
+
+EmulatedFakeCamera2::ConfigureThread::ConfigureThread(EmulatedFakeCamera2 *parent):
+        Thread(false),
+        mParent(parent),
+        mRequestCount(0),
+        mNextBuffers(NULL) {
+    mRunning = false;
+}
+
+EmulatedFakeCamera2::ConfigureThread::~ConfigureThread() {
+}
+
+status_t EmulatedFakeCamera2::ConfigureThread::readyToRun() {
+    Mutex::Autolock lock(mInputMutex);
+
+    ALOGV("Starting up ConfigureThread");
+    mRequest = NULL;
+    mActive  = false;
+    mRunning = true;
+
+    mInputSignal.signal();
+    return NO_ERROR;
+}
+
+status_t EmulatedFakeCamera2::ConfigureThread::waitUntilRunning() {
+    Mutex::Autolock lock(mInputMutex);
+    if (!mRunning) {
+        ALOGV("Waiting for configure thread to start");
+        mInputSignal.wait(mInputMutex);
+    }
+    return OK;
+}
+
+status_t EmulatedFakeCamera2::ConfigureThread::newRequestAvailable() {
+    waitUntilRunning();
+
+    Mutex::Autolock lock(mInputMutex);
+
+    mActive = true;
+    mInputSignal.signal();
+
+    return OK;
+}
+
+bool EmulatedFakeCamera2::ConfigureThread::isStreamInUse(uint32_t id) {
+    Mutex::Autolock lock(mInternalsMutex);
+
+    if (mNextBuffers == NULL) return false;
+    for (size_t i=0; i < mNextBuffers->size(); i++) {
+        if ((*mNextBuffers)[i].streamId == (int)id) return true;
+    }
+    return false;
+}
+
+int EmulatedFakeCamera2::ConfigureThread::getInProgressCount() {
+    Mutex::Autolock lock(mInputMutex);
+    return mRequestCount;
+}
+
+bool EmulatedFakeCamera2::ConfigureThread::threadLoop() {
+    status_t res;
+
+    // Check if we're currently processing or just waiting
+    {
+        Mutex::Autolock lock(mInputMutex);
+        if (!mActive) {
+            // Inactive, keep waiting until we've been signaled
+            status_t res;
+            res = mInputSignal.waitRelative(mInputMutex, kWaitPerLoop);
+            if (res != NO_ERROR && res != TIMED_OUT) {
+                ALOGE("%s: Error waiting for input requests: %d",
+                        __FUNCTION__, res);
+                return false;
+            }
+            if (!mActive) return true;
+            ALOGV("New request available");
+        }
+        // Active
+    }
+    if (mRequest == NULL) {
+        Mutex::Autolock il(mInternalsMutex);
+
+        ALOGV("Configure: Getting next request");
+        res = mParent->mRequestQueueSrc->dequeue_request(
+            mParent->mRequestQueueSrc,
+            &mRequest);
+        if (res != NO_ERROR) {
+            ALOGE("%s: Error dequeuing next request: %d", __FUNCTION__, res);
+            mParent->signalError();
+            return false;
+        }
+        if (mRequest == NULL) {
+            ALOGV("Configure: Request queue empty, going inactive");
+            // No requests available, go into inactive mode
+            Mutex::Autolock lock(mInputMutex);
+            mActive = false;
+            return true;
+        } else {
+            Mutex::Autolock lock(mInputMutex);
+            mRequestCount++;
+        }
+
+        camera_metadata_entry_t type;
+        res = find_camera_metadata_entry(mRequest,
+                ANDROID_REQUEST_TYPE,
+                &type);
+        if (res != NO_ERROR) {
+            ALOGE("%s: error reading request type", __FUNCTION__);
+            mParent->signalError();
+            return false;
+        }
+        bool success = false;;
+        switch (type.data.u8[0]) {
+            case ANDROID_REQUEST_TYPE_CAPTURE:
+                success = setupCapture();
+                break;
+            case ANDROID_REQUEST_TYPE_REPROCESS:
+                success = setupReprocess();
+                break;
+            default:
+                ALOGE("%s: Unexpected request type %d",
+                        __FUNCTION__, type.data.u8[0]);
+                mParent->signalError();
+                break;
+        }
+        if (!success) return false;
+
+    }
+
+    if (mWaitingForReadout) {
+        bool readoutDone;
+        readoutDone = mParent->mReadoutThread->waitForReady(kWaitPerLoop);
+        if (!readoutDone) return true;
+
+        if (mNextNeedsJpeg) {
+            ALOGV("Configure: Waiting for JPEG compressor");
+        } else {
+            ALOGV("Configure: Waiting for sensor");
+        }
+        mWaitingForReadout = false;
+    }
+
+    if (mNextNeedsJpeg) {
+        bool jpegDone;
+        jpegDone = mParent->mJpegCompressor->waitForDone(kWaitPerLoop);
+        if (!jpegDone) return true;
+
+        ALOGV("Configure: Waiting for sensor");
+        mNextNeedsJpeg = false;
+    }
+
+    if (mNextIsCapture) {
+        return configureNextCapture();
+    } else {
+        return configureNextReprocess();
+    }
+}
+
+bool EmulatedFakeCamera2::ConfigureThread::setupCapture() {
+    status_t res;
+
+    mNextIsCapture = true;
+    // Get necessary parameters for sensor config
+    mParent->mControlThread->processRequest(mRequest);
+
+    camera_metadata_entry_t streams;
+    res = find_camera_metadata_entry(mRequest,
+            ANDROID_REQUEST_OUTPUT_STREAMS,
+            &streams);
+    if (res != NO_ERROR) {
+        ALOGE("%s: error reading output stream tag", __FUNCTION__);
+        mParent->signalError();
+        return false;
+    }
+
+    mNextBuffers = new Buffers;
+    mNextNeedsJpeg = false;
+    ALOGV("Configure: Setting up buffers for capture");
+    for (size_t i = 0; i < streams.count; i++) {
+        int streamId = streams.data.u8[i];
+        const Stream &s = mParent->getStreamInfo(streamId);
+        if (s.format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
+            ALOGE("%s: Stream %d does not have a concrete pixel format, but "
+                    "is included in a request!", __FUNCTION__, streamId);
+            mParent->signalError();
+            return false;
+        }
+        StreamBuffer b;
+        b.streamId = streams.data.u8[i];
+        b.width  = s.width;
+        b.height = s.height;
+        b.format = s.format;
+        b.stride = s.stride;
+        mNextBuffers->push_back(b);
+        ALOGV("Configure:    Buffer %d: Stream %d, %d x %d, format 0x%x, "
+                "stride %d",
+                i, b.streamId, b.width, b.height, b.format, b.stride);
+        if (b.format == HAL_PIXEL_FORMAT_BLOB) {
+            mNextNeedsJpeg = true;
+        }
+    }
+
+    camera_metadata_entry_t e;
+    res = find_camera_metadata_entry(mRequest,
+            ANDROID_REQUEST_FRAME_COUNT,
+            &e);
+    if (res != NO_ERROR) {
+        ALOGE("%s: error reading frame count tag: %s (%d)",
+                __FUNCTION__, strerror(-res), res);
+        mParent->signalError();
+        return false;
+    }
+    mNextFrameNumber = *e.data.i32;
+
+    res = find_camera_metadata_entry(mRequest,
+            ANDROID_SENSOR_EXPOSURE_TIME,
+            &e);
+    if (res != NO_ERROR) {
+        ALOGE("%s: error reading exposure time tag: %s (%d)",
+                __FUNCTION__, strerror(-res), res);
+        mParent->signalError();
+        return false;
+    }
+    mNextExposureTime = *e.data.i64;
+
+    res = find_camera_metadata_entry(mRequest,
+            ANDROID_SENSOR_FRAME_DURATION,
+            &e);
+    if (res != NO_ERROR) {
+        ALOGE("%s: error reading frame duration tag", __FUNCTION__);
+        mParent->signalError();
+        return false;
+    }
+    mNextFrameDuration = *e.data.i64;
+
+    if (mNextFrameDuration <
+            mNextExposureTime + Sensor::kMinVerticalBlank) {
+        mNextFrameDuration = mNextExposureTime + Sensor::kMinVerticalBlank;
+    }
+    res = find_camera_metadata_entry(mRequest,
+            ANDROID_SENSOR_SENSITIVITY,
+            &e);
+    if (res != NO_ERROR) {
+        ALOGE("%s: error reading sensitivity tag", __FUNCTION__);
+        mParent->signalError();
+        return false;
+    }
+    mNextSensitivity = *e.data.i32;
+
+    res = find_camera_metadata_entry(mRequest,
+            EMULATOR_SCENE_HOUROFDAY,
+            &e);
+    if (res == NO_ERROR) {
+        ALOGV("Setting hour: %d", *e.data.i32);
+        mParent->mSensor->getScene().setHour(*e.data.i32);
+    }
+
+    // Start waiting on readout thread
+    mWaitingForReadout = true;
+    ALOGV("Configure: Waiting for readout thread");
+
+    return true;
+}
+
+bool EmulatedFakeCamera2::ConfigureThread::configureNextCapture() {
+    bool vsync = mParent->mSensor->waitForVSync(kWaitPerLoop);
+    if (!vsync) return true;
+
+    Mutex::Autolock il(mInternalsMutex);
+    ALOGV("Configure: Configuring sensor for capture %d", mNextFrameNumber);
+    mParent->mSensor->setExposureTime(mNextExposureTime);
+    mParent->mSensor->setFrameDuration(mNextFrameDuration);
+    mParent->mSensor->setSensitivity(mNextSensitivity);
+
+    getBuffers();
+
+    ALOGV("Configure: Done configure for capture %d", mNextFrameNumber);
+    mParent->mReadoutThread->setNextOperation(true, mRequest, mNextBuffers);
+    mParent->mSensor->setDestinationBuffers(mNextBuffers);
+
+    mRequest = NULL;
+    mNextBuffers = NULL;
+
+    Mutex::Autolock lock(mInputMutex);
+    mRequestCount--;
+
+    return true;
+}
+
+bool EmulatedFakeCamera2::ConfigureThread::setupReprocess() {
+    status_t res;
+
+    mNextNeedsJpeg = true;
+    mNextIsCapture = false;
+
+    camera_metadata_entry_t reprocessStreams;
+    res = find_camera_metadata_entry(mRequest,
+            ANDROID_REQUEST_INPUT_STREAMS,
+            &reprocessStreams);
+    if (res != NO_ERROR) {
+        ALOGE("%s: error reading output stream tag", __FUNCTION__);
+        mParent->signalError();
+        return false;
+    }
+
+    mNextBuffers = new Buffers;
+
+    ALOGV("Configure: Setting up input buffers for reprocess");
+    for (size_t i = 0; i < reprocessStreams.count; i++) {
+        int streamId = reprocessStreams.data.u8[i];
+        const ReprocessStream &s = mParent->getReprocessStreamInfo(streamId);
+        if (s.format != HAL_PIXEL_FORMAT_RGB_888) {
+            ALOGE("%s: Only ZSL reprocessing supported!",
+                    __FUNCTION__);
+            mParent->signalError();
+            return false;
+        }
+        StreamBuffer b;
+        b.streamId = -streamId;
+        b.width = s.width;
+        b.height = s.height;
+        b.format = s.format;
+        b.stride = s.stride;
+        mNextBuffers->push_back(b);
+    }
+
+    camera_metadata_entry_t streams;
+    res = find_camera_metadata_entry(mRequest,
+            ANDROID_REQUEST_OUTPUT_STREAMS,
+            &streams);
+    if (res != NO_ERROR) {
+        ALOGE("%s: error reading output stream tag", __FUNCTION__);
+        mParent->signalError();
+        return false;
+    }
+
+    ALOGV("Configure: Setting up output buffers for reprocess");
+    for (size_t i = 0; i < streams.count; i++) {
+        int streamId = streams.data.u8[i];
+        const Stream &s = mParent->getStreamInfo(streamId);
+        if (s.format != HAL_PIXEL_FORMAT_BLOB) {
+            // TODO: Support reprocess to YUV
+            ALOGE("%s: Non-JPEG output stream %d for reprocess not supported",
+                    __FUNCTION__, streamId);
+            mParent->signalError();
+            return false;
+        }
+        StreamBuffer b;
+        b.streamId = streams.data.u8[i];
+        b.width  = s.width;
+        b.height = s.height;
+        b.format = s.format;
+        b.stride = s.stride;
+        mNextBuffers->push_back(b);
+        ALOGV("Configure:    Buffer %d: Stream %d, %d x %d, format 0x%x, "
+                "stride %d",
+                i, b.streamId, b.width, b.height, b.format, b.stride);
+    }
+
+    camera_metadata_entry_t e;
+    res = find_camera_metadata_entry(mRequest,
+            ANDROID_REQUEST_FRAME_COUNT,
+            &e);
+    if (res != NO_ERROR) {
+        ALOGE("%s: error reading frame count tag: %s (%d)",
+                __FUNCTION__, strerror(-res), res);
+        mParent->signalError();
+        return false;
+    }
+    mNextFrameNumber = *e.data.i32;
+
+    return true;
+}
+
+bool EmulatedFakeCamera2::ConfigureThread::configureNextReprocess() {
+    Mutex::Autolock il(mInternalsMutex);
+
+    getBuffers();
+
+    ALOGV("Configure: Done configure for reprocess %d", mNextFrameNumber);
+    mParent->mReadoutThread->setNextOperation(false, mRequest, mNextBuffers);
+
+    mRequest = NULL;
+    mNextBuffers = NULL;
+
+    Mutex::Autolock lock(mInputMutex);
+    mRequestCount--;
+
+    return true;
+}
+
+bool EmulatedFakeCamera2::ConfigureThread::getBuffers() {
+    status_t res;
+    /** Get buffers to fill for this frame */
+    for (size_t i = 0; i < mNextBuffers->size(); i++) {
+        StreamBuffer &b = mNextBuffers->editItemAt(i);
+
+        if (b.streamId > 0) {
+            Stream s = mParent->getStreamInfo(b.streamId);
+            ALOGV("Configure: Dequeing buffer from stream %d", b.streamId);
+            res = s.ops->dequeue_buffer(s.ops, &(b.buffer) );
+            if (res != NO_ERROR || b.buffer == NULL) {
+                ALOGE("%s: Unable to dequeue buffer from stream %d: %s (%d)",
+                        __FUNCTION__, b.streamId, strerror(-res), res);
+                mParent->signalError();
+                return false;
+            }
+
+            /* Lock the buffer from the perspective of the graphics mapper */
+            const Rect rect(s.width, s.height);
+
+            res = GraphicBufferMapper::get().lock(*(b.buffer),
+                    GRALLOC_USAGE_HW_CAMERA_WRITE,
+                    rect, (void**)&(b.img) );
+
+            if (res != NO_ERROR) {
+                ALOGE("%s: grbuffer_mapper.lock failure: %s (%d)",
+                        __FUNCTION__, strerror(-res), res);
+                s.ops->cancel_buffer(s.ops,
+                        b.buffer);
+                mParent->signalError();
+                return false;
+            }
+        } else {
+            ReprocessStream s = mParent->getReprocessStreamInfo(-b.streamId);
+            ALOGV("Configure: Acquiring buffer from reprocess stream %d",
+                    -b.streamId);
+            res = s.ops->acquire_buffer(s.ops, &(b.buffer) );
+            if (res != NO_ERROR || b.buffer == NULL) {
+                ALOGE("%s: Unable to acquire buffer from reprocess stream %d: "
+                        "%s (%d)", __FUNCTION__, -b.streamId,
+                        strerror(-res), res);
+                mParent->signalError();
+                return false;
+            }
+
+            /* Lock the buffer from the perspective of the graphics mapper */
+            const Rect rect(s.width, s.height);
+
+            res = GraphicBufferMapper::get().lock(*(b.buffer),
+                    GRALLOC_USAGE_HW_CAMERA_READ,
+                    rect, (void**)&(b.img) );
+            if (res != NO_ERROR) {
+                ALOGE("%s: grbuffer_mapper.lock failure: %s (%d)",
+                        __FUNCTION__, strerror(-res), res);
+                s.ops->release_buffer(s.ops,
+                        b.buffer);
+                mParent->signalError();
+                return false;
+            }
+        }
+    }
+    return true;
+}
+
+EmulatedFakeCamera2::ReadoutThread::ReadoutThread(EmulatedFakeCamera2 *parent):
+        Thread(false),
+        mParent(parent),
+        mRunning(false),
+        mActive(false),
+        mRequestCount(0),
+        mRequest(NULL),
+        mBuffers(NULL) {
+    mInFlightQueue = new InFlightQueue[kInFlightQueueSize];
+    mInFlightHead = 0;
+    mInFlightTail = 0;
+}
+
+EmulatedFakeCamera2::ReadoutThread::~ReadoutThread() {
+    delete mInFlightQueue;
+}
+
+status_t EmulatedFakeCamera2::ReadoutThread::readyToRun() {
+    Mutex::Autolock lock(mInputMutex);
+    ALOGV("Starting up ReadoutThread");
+    mRunning = true;
+    mInputSignal.signal();
+    return NO_ERROR;
+}
+
+status_t EmulatedFakeCamera2::ReadoutThread::waitUntilRunning() {
+    Mutex::Autolock lock(mInputMutex);
+    if (!mRunning) {
+        ALOGV("Waiting for readout thread to start");
+        mInputSignal.wait(mInputMutex);
+    }
+    return OK;
+}
+
+bool EmulatedFakeCamera2::ReadoutThread::waitForReady(nsecs_t timeout) {
+    status_t res;
+    Mutex::Autolock lock(mInputMutex);
+    while (!readyForNextCapture()) {
+        res = mReadySignal.waitRelative(mInputMutex, timeout);
+        if (res == TIMED_OUT) return false;
+        if (res != OK) {
+            ALOGE("%s: Error waiting for ready: %s (%d)", __FUNCTION__,
+                    strerror(-res), res);
+            return false;
+        }
+    }
+    return true;
+}
+
+bool EmulatedFakeCamera2::ReadoutThread::readyForNextCapture() {
+    return (mInFlightTail + 1) % kInFlightQueueSize != mInFlightHead;
+}
+
+void EmulatedFakeCamera2::ReadoutThread::setNextOperation(
+        bool isCapture,
+        camera_metadata_t *request,
+        Buffers *buffers) {
+    Mutex::Autolock lock(mInputMutex);
+    if ( !readyForNextCapture() ) {
+        ALOGE("In flight queue full, dropping captures");
+        mParent->signalError();
+        return;
+    }
+    mInFlightQueue[mInFlightTail].isCapture = isCapture;
+    mInFlightQueue[mInFlightTail].request = request;
+    mInFlightQueue[mInFlightTail].buffers = buffers;
+    mInFlightTail = (mInFlightTail + 1) % kInFlightQueueSize;
+    mRequestCount++;
+
+    if (!mActive) {
+        mActive = true;
+        mInputSignal.signal();
+    }
+}
+
+bool EmulatedFakeCamera2::ReadoutThread::isStreamInUse(uint32_t id) {
+    // acquire in same order as threadLoop
+    Mutex::Autolock iLock(mInternalsMutex);
+    Mutex::Autolock lock(mInputMutex);
+
+    size_t i = mInFlightHead;
+    while (i != mInFlightTail) {
+        for (size_t j = 0; j < mInFlightQueue[i].buffers->size(); j++) {
+            if ( (*(mInFlightQueue[i].buffers))[j].streamId == (int)id )
+                return true;
+        }
+        i = (i + 1) % kInFlightQueueSize;
+    }
+
+
+    if (mBuffers != NULL) {
+        for (i = 0; i < mBuffers->size(); i++) {
+            if ( (*mBuffers)[i].streamId == (int)id) return true;
+        }
+    }
+
+    return false;
+}
+
+int EmulatedFakeCamera2::ReadoutThread::getInProgressCount() {
+    Mutex::Autolock lock(mInputMutex);
+
+    return mRequestCount;
+}
+
+bool EmulatedFakeCamera2::ReadoutThread::threadLoop() {
+    static const nsecs_t kWaitPerLoop = 10000000L; // 10 ms
+    status_t res;
+    int32_t frameNumber;
+
+    // Check if we're currently processing or just waiting
+    {
+        Mutex::Autolock lock(mInputMutex);
+        if (!mActive) {
+            // Inactive, keep waiting until we've been signaled
+            res = mInputSignal.waitRelative(mInputMutex, kWaitPerLoop);
+            if (res != NO_ERROR && res != TIMED_OUT) {
+                ALOGE("%s: Error waiting for capture requests: %d",
+                        __FUNCTION__, res);
+                mParent->signalError();
+                return false;
+            }
+            if (!mActive) return true;
+        }
+        // Active, see if we need a new request
+        if (mRequest == NULL) {
+            if (mInFlightHead == mInFlightTail) {
+                // Go inactive
+                ALOGV("Waiting for sensor data");
+                mActive = false;
+                return true;
+            } else {
+                Mutex::Autolock iLock(mInternalsMutex);
+                mReadySignal.signal();
+                mIsCapture = mInFlightQueue[mInFlightHead].isCapture;
+                mRequest = mInFlightQueue[mInFlightHead].request;
+                mBuffers  = mInFlightQueue[mInFlightHead].buffers;
+                mInFlightQueue[mInFlightHead].request = NULL;
+                mInFlightQueue[mInFlightHead].buffers = NULL;
+                mInFlightHead = (mInFlightHead + 1) % kInFlightQueueSize;
+                ALOGV("Ready to read out request %p, %d buffers",
+                        mRequest, mBuffers->size());
+            }
+        }
+    }
+
+    // Active with request, wait on sensor to complete
+
+    nsecs_t captureTime;
+
+    if (mIsCapture) {
+        bool gotFrame;
+        gotFrame = mParent->mSensor->waitForNewFrame(kWaitPerLoop,
+                &captureTime);
+
+        if (!gotFrame) return true;
+    }
+
+    Mutex::Autolock iLock(mInternalsMutex);
+
+    camera_metadata_entry_t entry;
+    if (!mIsCapture) {
+        res = find_camera_metadata_entry(mRequest,
+                ANDROID_SENSOR_TIMESTAMP,
+            &entry);
+        if (res != NO_ERROR) {
+            ALOGE("%s: error reading reprocessing timestamp: %s (%d)",
+                    __FUNCTION__, strerror(-res), res);
+            mParent->signalError();
+            return false;
+        }
+        captureTime = entry.data.i64[0];
+    }
+
+    res = find_camera_metadata_entry(mRequest,
+            ANDROID_REQUEST_FRAME_COUNT,
+            &entry);
+    if (res != NO_ERROR) {
+        ALOGE("%s: error reading frame count tag: %s (%d)",
+                __FUNCTION__, strerror(-res), res);
+        mParent->signalError();
+        return false;
+    }
+    frameNumber = *entry.data.i32;
+
+    res = find_camera_metadata_entry(mRequest,
+            ANDROID_REQUEST_METADATA_MODE,
+            &entry);
+    if (res != NO_ERROR) {
+        ALOGE("%s: error reading metadata mode tag: %s (%d)",
+                __FUNCTION__, strerror(-res), res);
+        mParent->signalError();
+        return false;
+    }
+
+    // Got sensor data and request, construct frame and send it out
+    ALOGV("Readout: Constructing metadata and frames for request %d",
+            frameNumber);
+
+    if (*entry.data.u8 == ANDROID_REQUEST_METADATA_MODE_FULL) {
+        ALOGV("Readout: Metadata requested, constructing");
+
+        camera_metadata_t *frame = NULL;
+
+        size_t frame_entries = get_camera_metadata_entry_count(mRequest);
+        size_t frame_data    = get_camera_metadata_data_count(mRequest);
+
+        // TODO: Dynamically calculate based on enabled statistics, etc
+        frame_entries += 10;
+        frame_data += 100;
+
+        res = mParent->mFrameQueueDst->dequeue_frame(mParent->mFrameQueueDst,
+                frame_entries, frame_data, &frame);
+
+        if (res != NO_ERROR || frame == NULL) {
+            ALOGE("%s: Unable to dequeue frame metadata buffer", __FUNCTION__);
+            mParent->signalError();
+            return false;
+        }
+
+        res = append_camera_metadata(frame, mRequest);
+        if (res != NO_ERROR) {
+            ALOGE("Unable to append request metadata");
+        }
+
+        if (mIsCapture) {
+            add_camera_metadata_entry(frame,
+                    ANDROID_SENSOR_TIMESTAMP,
+                    &captureTime,
+                    1);
+
+            int32_t hourOfDay = (int32_t)mParent->mSensor->getScene().getHour();
+            camera_metadata_entry_t requestedHour;
+            res = find_camera_metadata_entry(frame,
+                    EMULATOR_SCENE_HOUROFDAY,
+                    &requestedHour);
+            if (res == NAME_NOT_FOUND) {
+                res = add_camera_metadata_entry(frame,
+                        EMULATOR_SCENE_HOUROFDAY,
+                        &hourOfDay, 1);
+                if (res != NO_ERROR) {
+                    ALOGE("Unable to add vendor tag");
+                }
+            } else if (res == OK) {
+                *requestedHour.data.i32 = hourOfDay;
+            } else {
+                ALOGE("%s: Error looking up vendor tag", __FUNCTION__);
+            }
+
+            collectStatisticsMetadata(frame);
+            // TODO: Collect all final values used from sensor in addition to timestamp
+        }
+
+        ALOGV("Readout: Enqueue frame %d", frameNumber);
+        mParent->mFrameQueueDst->enqueue_frame(mParent->mFrameQueueDst,
+                frame);
+    }
+    ALOGV("Readout: Free request");
+    res = mParent->mRequestQueueSrc->free_request(mParent->mRequestQueueSrc, mRequest);
+    if (res != NO_ERROR) {
+        ALOGE("%s: Unable to return request buffer to queue: %d",
+                __FUNCTION__, res);
+        mParent->signalError();
+        return false;
+    }
+    mRequest = NULL;
+
+    int compressedBufferIndex = -1;
+    ALOGV("Readout: Processing %d buffers", mBuffers->size());
+    for (size_t i = 0; i < mBuffers->size(); i++) {
+        const StreamBuffer &b = (*mBuffers)[i];
+        ALOGV("Readout:    Buffer %d: Stream %d, %d x %d, format 0x%x, stride %d",
+                i, b.streamId, b.width, b.height, b.format, b.stride);
+        if (b.streamId > 0) {
+            if (b.format == HAL_PIXEL_FORMAT_BLOB) {
+                // Assumes only one BLOB buffer type per capture
+                compressedBufferIndex = i;
+            } else {
+                ALOGV("Readout:    Sending image buffer %d (%p) to output stream %d",
+                        i, (void*)*(b.buffer), b.streamId);
+                GraphicBufferMapper::get().unlock(*(b.buffer));
+                const Stream &s = mParent->getStreamInfo(b.streamId);
+                res = s.ops->enqueue_buffer(s.ops, captureTime, b.buffer);
+                if (res != OK) {
+                    ALOGE("Error enqueuing image buffer %p: %s (%d)", b.buffer,
+                            strerror(-res), res);
+                    mParent->signalError();
+                }
+            }
+        }
+    }
+
+    if (compressedBufferIndex == -1) {
+        delete mBuffers;
+        mBuffers = NULL;
+    } else {
+        ALOGV("Readout:  Starting JPEG compression for buffer %d, stream %d",
+                compressedBufferIndex,
+                (*mBuffers)[compressedBufferIndex].streamId);
+        mParent->mJpegCompressor->start(mBuffers, captureTime);
+        mBuffers = NULL;
+    }
+
+    Mutex::Autolock l(mInputMutex);
+    mRequestCount--;
+    ALOGV("Readout: Done with request %d", frameNumber);
+    return true;
+}
+
+status_t EmulatedFakeCamera2::ReadoutThread::collectStatisticsMetadata(
+        camera_metadata_t *frame) {
+    // Completely fake face rectangles, don't correspond to real faces in scene
+    ALOGV("Readout:    Collecting statistics metadata");
+
+    status_t res;
+    camera_metadata_entry_t entry;
+    res = find_camera_metadata_entry(frame,
+                ANDROID_STATISTICS_FACE_DETECT_MODE,
+                &entry);
+    if (res != OK) {
+        ALOGE("%s: Unable to find face detect mode!", __FUNCTION__);
+        return BAD_VALUE;
+    }
+
+    if (entry.data.u8[0] == ANDROID_STATISTICS_FACE_DETECT_MODE_OFF) return OK;
+
+    // The coordinate system for the face regions is the raw sensor pixel
+    // coordinates. Here, we map from the scene coordinates (0-19 in both axis)
+    // to raw pixels, for the scene defined in fake-pipeline2/Scene.cpp. We
+    // approximately place two faces on top of the windows of the house. No
+    // actual faces exist there, but might one day. Note that this doesn't
+    // account for the offsets used to account for aspect ratio differences, so
+    // the rectangles don't line up quite right.
+    const size_t numFaces = 2;
+    int32_t rects[numFaces * 4] = {
+            Sensor::kResolution[0] * 10 / 20,
+            Sensor::kResolution[1] * 15 / 20,
+            Sensor::kResolution[0] * 12 / 20,
+            Sensor::kResolution[1] * 17 / 20,
+
+            Sensor::kResolution[0] * 16 / 20,
+            Sensor::kResolution[1] * 15 / 20,
+            Sensor::kResolution[0] * 18 / 20,
+            Sensor::kResolution[1] * 17 / 20
+    };
+    // To simulate some kind of real detection going on, we jitter the rectangles on
+    // each frame by a few pixels in each dimension.
+    for (size_t i = 0; i < numFaces * 4; i++) {
+        rects[i] += (int32_t)(((float)rand() / RAND_MAX) * 6 - 3);
+    }
+    // The confidence scores (0-100) are similarly jittered.
+    uint8_t scores[numFaces] = { 85, 95 };
+    for (size_t i = 0; i < numFaces; i++) {
+        scores[i] += (int32_t)(((float)rand() / RAND_MAX) * 10 - 5);
+    }
+
+    res = add_camera_metadata_entry(frame, ANDROID_STATISTICS_FACE_RECTANGLES,
+            rects, numFaces * 4);
+    if (res != OK) {
+        ALOGE("%s: Unable to add face rectangles!", __FUNCTION__);
+        return BAD_VALUE;
+    }
+
+    res = add_camera_metadata_entry(frame, ANDROID_STATISTICS_FACE_SCORES,
+            scores, numFaces);
+    if (res != OK) {
+        ALOGE("%s: Unable to add face scores!", __FUNCTION__);
+        return BAD_VALUE;
+    }
+
+    if (entry.data.u8[0] == ANDROID_STATISTICS_FACE_DETECT_MODE_SIMPLE) return OK;
+
+    // Advanced face detection options - add eye/mouth coordinates.  The
+    // coordinates in order are (leftEyeX, leftEyeY, rightEyeX, rightEyeY,
+    // mouthX, mouthY). The mapping is the same as the face rectangles.
+    int32_t features[numFaces * 6] = {
+        Sensor::kResolution[0] * 10.5 / 20,
+        Sensor::kResolution[1] * 16 / 20,
+        Sensor::kResolution[0] * 11.5 / 20,
+        Sensor::kResolution[1] * 16 / 20,
+        Sensor::kResolution[0] * 11 / 20,
+        Sensor::kResolution[1] * 16.5 / 20,
+
+        Sensor::kResolution[0] * 16.5 / 20,
+        Sensor::kResolution[1] * 16 / 20,
+        Sensor::kResolution[0] * 17.5 / 20,
+        Sensor::kResolution[1] * 16 / 20,
+        Sensor::kResolution[0] * 17 / 20,
+        Sensor::kResolution[1] * 16.5 / 20,
+    };
+    // Jitter these a bit less than the rects
+    for (size_t i = 0; i < numFaces * 6; i++) {
+        features[i] += (int32_t)(((float)rand() / RAND_MAX) * 4 - 2);
+    }
+    // These are unique IDs that are used to identify each face while it's
+    // visible to the detector (if a face went away and came back, it'd get a
+    // new ID).
+    int32_t ids[numFaces] = {
+        100, 200
+    };
+
+    res = add_camera_metadata_entry(frame, ANDROID_STATISTICS_FACE_LANDMARKS,
+            features, numFaces * 6);
+    if (res != OK) {
+        ALOGE("%s: Unable to add face landmarks!", __FUNCTION__);
+        return BAD_VALUE;
+    }
+
+    res = add_camera_metadata_entry(frame, ANDROID_STATISTICS_FACE_IDS,
+            ids, numFaces);
+    if (res != OK) {
+        ALOGE("%s: Unable to add face scores!", __FUNCTION__);
+        return BAD_VALUE;
+    }
+
+    return OK;
+}
+
+EmulatedFakeCamera2::ControlThread::ControlThread(EmulatedFakeCamera2 *parent):
+        Thread(false),
+        mParent(parent) {
+    mRunning = false;
+}
+
+EmulatedFakeCamera2::ControlThread::~ControlThread() {
+}
+
+status_t EmulatedFakeCamera2::ControlThread::readyToRun() {
+    Mutex::Autolock lock(mInputMutex);
+
+    ALOGV("Starting up ControlThread");
+    mRunning = true;
+    mStartAf = false;
+    mCancelAf = false;
+    mStartPrecapture = false;
+
+    mControlMode = ANDROID_CONTROL_MODE_AUTO;
+
+    mEffectMode = ANDROID_CONTROL_EFFECT_MODE_OFF;
+    mSceneMode = ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY;
+
+    mAfMode = ANDROID_CONTROL_AF_MODE_AUTO;
+    mAfModeChange = false;
+
+    mAeMode = ANDROID_CONTROL_AE_MODE_ON;
+    mAwbMode = ANDROID_CONTROL_AWB_MODE_AUTO;
+
+    mAfTriggerId = 0;
+    mPrecaptureTriggerId = 0;
+
+    mAfState = ANDROID_CONTROL_AF_STATE_INACTIVE;
+    mAeState = ANDROID_CONTROL_AE_STATE_INACTIVE;
+    mAwbState = ANDROID_CONTROL_AWB_STATE_INACTIVE;
+
+    mExposureTime = kNormalExposureTime;
+
+    mInputSignal.signal();
+    return NO_ERROR;
+}
+
+status_t EmulatedFakeCamera2::ControlThread::waitUntilRunning() {
+    Mutex::Autolock lock(mInputMutex);
+    if (!mRunning) {
+        ALOGV("Waiting for control thread to start");
+        mInputSignal.wait(mInputMutex);
+    }
+    return OK;
+}
+
+// Override android.control.* fields with 3A values before sending request to sensor
+status_t EmulatedFakeCamera2::ControlThread::processRequest(camera_metadata_t *request) {
+    Mutex::Autolock lock(mInputMutex);
+    // TODO: Add handling for all android.control.* fields here
+    camera_metadata_entry_t mode;
+    status_t res;
+
+#define READ_IF_OK(res, what, def)                                             \
+    (((res) == OK) ? (what) : (uint8_t)(def))
+
+    res = find_camera_metadata_entry(request,
+            ANDROID_CONTROL_MODE,
+            &mode);
+    mControlMode = READ_IF_OK(res, mode.data.u8[0], ANDROID_CONTROL_MODE_OFF);
+
+    // disable all 3A
+    if (mControlMode == ANDROID_CONTROL_MODE_OFF) {
+        mEffectMode =   ANDROID_CONTROL_EFFECT_MODE_OFF;
+        mSceneMode =    ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED;
+        mAfMode =       ANDROID_CONTROL_AF_MODE_OFF;
+        mAeLock =       ANDROID_CONTROL_AE_LOCK_ON;
+        mAeMode =       ANDROID_CONTROL_AE_MODE_OFF;
+        mAfModeChange = true;
+        mStartAf =      false;
+        mCancelAf =     true;
+        mAeState =      ANDROID_CONTROL_AE_STATE_INACTIVE;
+        mAwbMode =      ANDROID_CONTROL_AWB_MODE_OFF;
+        return res;
+    }
+
+    res = find_camera_metadata_entry(request,
+            ANDROID_CONTROL_EFFECT_MODE,
+            &mode);
+    mEffectMode = READ_IF_OK(res, mode.data.u8[0],
+                             ANDROID_CONTROL_EFFECT_MODE_OFF);
+
+    res = find_camera_metadata_entry(request,
+            ANDROID_CONTROL_SCENE_MODE,
+            &mode);
+    mSceneMode = READ_IF_OK(res, mode.data.u8[0],
+                             ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED);
+
+    res = find_camera_metadata_entry(request,
+            ANDROID_CONTROL_AF_MODE,
+            &mode);
+    if (mAfMode != mode.data.u8[0]) {
+        ALOGV("AF new mode: %d, old mode %d", mode.data.u8[0], mAfMode);
+        mAfMode = mode.data.u8[0];
+        mAfModeChange = true;
+        mStartAf = false;
+        mCancelAf = false;
+    }
+
+    res = find_camera_metadata_entry(request,
+            ANDROID_CONTROL_AE_MODE,
+            &mode);
+    mAeMode = READ_IF_OK(res, mode.data.u8[0],
+                             ANDROID_CONTROL_AE_MODE_OFF);
+
+    res = find_camera_metadata_entry(request,
+            ANDROID_CONTROL_AE_LOCK,
+            &mode);
+    uint8_t aeLockVal = READ_IF_OK(res, mode.data.u8[0],
+                                   ANDROID_CONTROL_AE_LOCK_ON);
+    bool aeLock = (aeLockVal == ANDROID_CONTROL_AE_LOCK_ON);
+    if (mAeLock && !aeLock) {
+        mAeState = ANDROID_CONTROL_AE_STATE_INACTIVE;
+    }
+    mAeLock = aeLock;
+
+    res = find_camera_metadata_entry(request,
+            ANDROID_CONTROL_AWB_MODE,
+            &mode);
+    mAwbMode = READ_IF_OK(res, mode.data.u8[0],
+                          ANDROID_CONTROL_AWB_MODE_OFF);
+
+    // TODO: Override more control fields
+
+    if (mAeMode != ANDROID_CONTROL_AE_MODE_OFF) {
+        camera_metadata_entry_t exposureTime;
+        res = find_camera_metadata_entry(request,
+                ANDROID_SENSOR_EXPOSURE_TIME,
+                &exposureTime);
+        if (res == OK) {
+            exposureTime.data.i64[0] = mExposureTime;
+        }
+    }
+
+#undef READ_IF_OK
+
+    return OK;
+}
+
+status_t EmulatedFakeCamera2::ControlThread::triggerAction(uint32_t msgType,
+        int32_t ext1, int32_t ext2) {
+    ALOGV("%s: Triggering %d (%d, %d)", __FUNCTION__, msgType, ext1, ext2);
+    Mutex::Autolock lock(mInputMutex);
+    switch (msgType) {
+        case CAMERA2_TRIGGER_AUTOFOCUS:
+            mAfTriggerId = ext1;
+            mStartAf = true;
+            mCancelAf = false;
+            break;
+        case CAMERA2_TRIGGER_CANCEL_AUTOFOCUS:
+            mAfTriggerId = ext1;
+            mStartAf = false;
+            mCancelAf = true;
+            break;
+        case CAMERA2_TRIGGER_PRECAPTURE_METERING:
+            mPrecaptureTriggerId = ext1;
+            mStartPrecapture = true;
+            break;
+        default:
+            ALOGE("%s: Unknown action triggered: %d (arguments %d %d)",
+                    __FUNCTION__, msgType, ext1, ext2);
+            return BAD_VALUE;
+    }
+    return OK;
+}
+
+const nsecs_t EmulatedFakeCamera2::ControlThread::kControlCycleDelay = 100 * MSEC;
+const nsecs_t EmulatedFakeCamera2::ControlThread::kMinAfDuration = 500 * MSEC;
+const nsecs_t EmulatedFakeCamera2::ControlThread::kMaxAfDuration = 900 * MSEC;
+const float EmulatedFakeCamera2::ControlThread::kAfSuccessRate = 0.9;
+ // Once every 5 seconds
+const float EmulatedFakeCamera2::ControlThread::kContinuousAfStartRate =
+        kControlCycleDelay / 5.0 * SEC;
+const nsecs_t EmulatedFakeCamera2::ControlThread::kMinAeDuration = 500 * MSEC;
+const nsecs_t EmulatedFakeCamera2::ControlThread::kMaxAeDuration = 2 * SEC;
+const nsecs_t EmulatedFakeCamera2::ControlThread::kMinPrecaptureAeDuration = 100 * MSEC;
+const nsecs_t EmulatedFakeCamera2::ControlThread::kMaxPrecaptureAeDuration = 400 * MSEC;
+ // Once every 3 seconds
+const float EmulatedFakeCamera2::ControlThread::kAeScanStartRate =
+    kControlCycleDelay / 3000000000.0;
+
+const nsecs_t EmulatedFakeCamera2::ControlThread::kNormalExposureTime = 10 * MSEC;
+const nsecs_t EmulatedFakeCamera2::ControlThread::kExposureJump = 2 * MSEC;
+const nsecs_t EmulatedFakeCamera2::ControlThread::kMinExposureTime = 1 * MSEC;
+
+bool EmulatedFakeCamera2::ControlThread::threadLoop() {
+    bool afModeChange = false;
+    bool afTriggered = false;
+    bool afCancelled = false;
+    uint8_t afState;
+    uint8_t afMode;
+    int32_t afTriggerId;
+    bool precaptureTriggered = false;
+    uint8_t aeState;
+    uint8_t aeMode;
+    bool    aeLock;
+    int32_t precaptureTriggerId;
+    nsecs_t nextSleep = kControlCycleDelay;
+
+    {
+        Mutex::Autolock lock(mInputMutex);
+        if (mStartAf) {
+            ALOGD("Starting AF trigger processing");
+            afTriggered = true;
+            mStartAf = false;
+        } else if (mCancelAf) {
+            ALOGD("Starting cancel AF trigger processing");
+            afCancelled = true;
+            mCancelAf = false;
+        }
+        afState = mAfState;
+        afMode = mAfMode;
+        afModeChange = mAfModeChange;
+        mAfModeChange = false;
+
+        afTriggerId = mAfTriggerId;
+
+        if(mStartPrecapture) {
+            ALOGD("Starting precapture trigger processing");
+            precaptureTriggered = true;
+            mStartPrecapture = false;
+        }
+        aeState = mAeState;
+        aeMode = mAeMode;
+        aeLock = mAeLock;
+        precaptureTriggerId = mPrecaptureTriggerId;
+    }
+
+    if (afCancelled || afModeChange) {
+        ALOGV("Resetting AF state due to cancel/mode change");
+        afState = ANDROID_CONTROL_AF_STATE_INACTIVE;
+        updateAfState(afState, afTriggerId);
+        mAfScanDuration = 0;
+        mLockAfterPassiveScan = false;
+    }
+
+    uint8_t oldAfState = afState;
+
+    if (afTriggered) {
+        afState = processAfTrigger(afMode, afState);
+    }
+
+    afState = maybeStartAfScan(afMode, afState);
+    afState = updateAfScan(afMode, afState, &nextSleep);
+    updateAfState(afState, afTriggerId);
+
+    if (precaptureTriggered) {
+        aeState = processPrecaptureTrigger(aeMode, aeState);
+    }
+
+    aeState = maybeStartAeScan(aeMode, aeLock, aeState);
+    aeState = updateAeScan(aeMode, aeLock, aeState, &nextSleep);
+    updateAeState(aeState, precaptureTriggerId);
+
+    int ret;
+    timespec t;
+    t.tv_sec = 0;
+    t.tv_nsec = nextSleep;
+    do {
+        ret = nanosleep(&t, &t);
+    } while (ret != 0);
+
+    if (mAfScanDuration > 0) {
+        mAfScanDuration -= nextSleep;
+    }
+    if (mAeScanDuration > 0) {
+        mAeScanDuration -= nextSleep;
+    }
+
+    return true;
+}
+
+int EmulatedFakeCamera2::ControlThread::processAfTrigger(uint8_t afMode,
+        uint8_t afState) {
+    switch (afMode) {
+        case ANDROID_CONTROL_AF_MODE_OFF:
+        case ANDROID_CONTROL_AF_MODE_EDOF:
+            // Do nothing
+            break;
+        case ANDROID_CONTROL_AF_MODE_MACRO:
+        case ANDROID_CONTROL_AF_MODE_AUTO:
+            switch (afState) {
+                case ANDROID_CONTROL_AF_STATE_INACTIVE:
+                case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED:
+                case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
+                    // Start new focusing cycle
+                    mAfScanDuration =  ((double)rand() / RAND_MAX) *
+                        (kMaxAfDuration - kMinAfDuration) + kMinAfDuration;
+                    afState = ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN;
+                    ALOGV("%s: AF scan start, duration %lld ms",
+                          __FUNCTION__, mAfScanDuration / 1000000);
+                    break;
+                case ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN:
+                    // Ignore new request, already scanning
+                    break;
+                default:
+                    ALOGE("Unexpected AF state in AUTO/MACRO AF mode: %d",
+                          afState);
+            }
+            break;
+        case ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE:
+            switch (afState) {
+                // Picture mode waits for passive scan to complete
+                case ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN:
+                    mLockAfterPassiveScan = true;
+                    break;
+                case ANDROID_CONTROL_AF_STATE_INACTIVE:
+                    afState = ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED;
+                    break;
+                case ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED:
+                    afState = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED;
+                    break;
+                case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED:
+                case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
+                    // Must cancel to get out of these states
+                    break;
+                default:
+                    ALOGE("Unexpected AF state in CONTINUOUS_PICTURE AF mode: %d",
+                          afState);
+            }
+            break;
+        case ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO:
+            switch (afState) {
+                // Video mode does not wait for passive scan to complete
+                case ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN:
+                case ANDROID_CONTROL_AF_STATE_INACTIVE:
+                    afState = ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED;
+                    break;
+                case ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED:
+                    afState = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED;
+                    break;
+                case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED:
+                case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
+                    // Must cancel to get out of these states
+                    break;
+                default:
+                    ALOGE("Unexpected AF state in CONTINUOUS_VIDEO AF mode: %d",
+                          afState);
+            }
+            break;
+        default:
+            break;
+    }
+    return afState;
+}
+
+int EmulatedFakeCamera2::ControlThread::maybeStartAfScan(uint8_t afMode,
+        uint8_t afState) {
+    if ((afMode == ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO ||
+            afMode == ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE) &&
+        (afState == ANDROID_CONTROL_AF_STATE_INACTIVE ||
+            afState == ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED)) {
+
+        bool startScan = ((double)rand() / RAND_MAX) < kContinuousAfStartRate;
+        if (startScan) {
+            // Start new passive focusing cycle
+            mAfScanDuration =  ((double)rand() / RAND_MAX) *
+                (kMaxAfDuration - kMinAfDuration) + kMinAfDuration;
+            afState = ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN;
+            ALOGV("%s: AF passive scan start, duration %lld ms",
+                __FUNCTION__, mAfScanDuration / 1000000);
+        }
+    }
+    return afState;
+}
+
+int EmulatedFakeCamera2::ControlThread::updateAfScan(uint8_t afMode,
+        uint8_t afState, nsecs_t *maxSleep) {
+    if (! (afState == ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN ||
+            afState == ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN ) ) {
+        return afState;
+    }
+
+    if (mAfScanDuration <= 0) {
+        ALOGV("%s: AF scan done", __FUNCTION__);
+        switch (afMode) {
+            case ANDROID_CONTROL_AF_MODE_MACRO:
+            case ANDROID_CONTROL_AF_MODE_AUTO: {
+                bool success = ((double)rand() / RAND_MAX) < kAfSuccessRate;
+                if (success) {
+                    afState = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED;
+                } else {
+                    afState = ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED;
+                }
+                break;
+            }
+            case ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE:
+                if (mLockAfterPassiveScan) {
+                    afState = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED;
+                    mLockAfterPassiveScan = false;
+                } else {
+                    afState = ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED;
+                }
+                break;
+            case ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO:
+                afState = ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED;
+                break;
+            default:
+                ALOGE("Unexpected AF mode in scan state");
+        }
+    } else {
+        if (mAfScanDuration <= *maxSleep) {
+            *maxSleep = mAfScanDuration;
+        }
+    }
+    return afState;
+}
+
+void EmulatedFakeCamera2::ControlThread::updateAfState(uint8_t newState,
+        int32_t triggerId) {
+    Mutex::Autolock lock(mInputMutex);
+    if (mAfState != newState) {
+        ALOGV("%s: Autofocus state now %d, id %d", __FUNCTION__,
+                newState, triggerId);
+        mAfState = newState;
+        mParent->sendNotification(CAMERA2_MSG_AUTOFOCUS,
+                newState, triggerId, 0);
+    }
+}
+
+int EmulatedFakeCamera2::ControlThread::processPrecaptureTrigger(uint8_t aeMode,
+        uint8_t aeState) {
+    switch (aeMode) {
+        case ANDROID_CONTROL_AE_MODE_OFF:
+            // Don't do anything for these
+            return aeState;
+        case ANDROID_CONTROL_AE_MODE_ON:
+        case ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH:
+        case ANDROID_CONTROL_AE_MODE_ON_ALWAYS_FLASH:
+        case ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE:
+            // Trigger a precapture cycle
+            aeState = ANDROID_CONTROL_AE_STATE_PRECAPTURE;
+            mAeScanDuration = ((double)rand() / RAND_MAX) *
+                    (kMaxPrecaptureAeDuration - kMinPrecaptureAeDuration) +
+                    kMinPrecaptureAeDuration;
+            ALOGD("%s: AE precapture scan start, duration %lld ms",
+                    __FUNCTION__, mAeScanDuration / 1000000);
+
+    }
+    return aeState;
+}
+
+int EmulatedFakeCamera2::ControlThread::maybeStartAeScan(uint8_t aeMode,
+        bool aeLocked,
+        uint8_t aeState) {
+    if (aeLocked) return aeState;
+    switch (aeMode) {
+        case ANDROID_CONTROL_AE_MODE_OFF:
+            break;
+        case ANDROID_CONTROL_AE_MODE_ON:
+        case ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH:
+        case ANDROID_CONTROL_AE_MODE_ON_ALWAYS_FLASH:
+        case ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE: {
+            if (aeState != ANDROID_CONTROL_AE_STATE_INACTIVE &&
+                    aeState != ANDROID_CONTROL_AE_STATE_CONVERGED) break;
+
+            bool startScan = ((double)rand() / RAND_MAX) < kAeScanStartRate;
+            if (startScan) {
+                mAeScanDuration = ((double)rand() / RAND_MAX) *
+                (kMaxAeDuration - kMinAeDuration) + kMinAeDuration;
+                aeState = ANDROID_CONTROL_AE_STATE_SEARCHING;
+                ALOGD("%s: AE scan start, duration %lld ms",
+                        __FUNCTION__, mAeScanDuration / 1000000);
+            }
+        }
+    }
+
+    return aeState;
+}
+
+int EmulatedFakeCamera2::ControlThread::updateAeScan(uint8_t aeMode,
+        bool aeLock, uint8_t aeState, nsecs_t *maxSleep) {
+    if (aeLock && aeState != ANDROID_CONTROL_AE_STATE_PRECAPTURE) {
+        mAeScanDuration = 0;
+        aeState = ANDROID_CONTROL_AE_STATE_LOCKED;
+    } else if ((aeState == ANDROID_CONTROL_AE_STATE_SEARCHING) ||
+            (aeState == ANDROID_CONTROL_AE_STATE_PRECAPTURE ) ) {
+        if (mAeScanDuration <= 0) {
+            ALOGD("%s: AE scan done", __FUNCTION__);
+            aeState = aeLock ?
+                    ANDROID_CONTROL_AE_STATE_LOCKED :ANDROID_CONTROL_AE_STATE_CONVERGED;
+
+            Mutex::Autolock lock(mInputMutex);
+            mExposureTime = kNormalExposureTime;
+        } else {
+            if (mAeScanDuration <= *maxSleep) {
+                *maxSleep = mAeScanDuration;
+            }
+
+            int64_t exposureDelta =
+                    ((double)rand() / RAND_MAX) * 2 * kExposureJump -
+                    kExposureJump;
+            Mutex::Autolock lock(mInputMutex);
+            mExposureTime = mExposureTime + exposureDelta;
+            if (mExposureTime < kMinExposureTime) mExposureTime = kMinExposureTime;
+        }
+    }
+
+    return aeState;
+}
+
+
+void EmulatedFakeCamera2::ControlThread::updateAeState(uint8_t newState,
+        int32_t triggerId) {
+    Mutex::Autolock lock(mInputMutex);
+    if (mAeState != newState) {
+        ALOGD("%s: Autoexposure state now %d, id %d", __FUNCTION__,
+                newState, triggerId);
+        mAeState = newState;
+        mParent->sendNotification(CAMERA2_MSG_AUTOEXPOSURE,
+                newState, triggerId, 0);
+    }
+}
+
+/** Private methods */
+
+status_t EmulatedFakeCamera2::constructStaticInfo(
+        camera_metadata_t **info,
+        bool sizeRequest) const {
+
+    size_t entryCount = 0;
+    size_t dataCount = 0;
+    status_t ret;
+
+#define ADD_OR_SIZE( tag, data, count ) \
+    if ( ( ret = addOrSize(*info, sizeRequest, &entryCount, &dataCount, \
+            tag, data, count) ) != OK ) return ret
+
+    // android.lens
+
+    // 5 cm min focus distance for back camera, infinity (fixed focus) for front
+    const float minFocusDistance = mFacingBack ? 1.0/0.05 : 0.0;
+    ADD_OR_SIZE(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
+            &minFocusDistance, 1);
+    // 5 m hyperfocal distance for back camera, infinity (fixed focus) for front
+    const float hyperFocalDistance = mFacingBack ? 1.0/5.0 : 0.0;
+    ADD_OR_SIZE(ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
+            &minFocusDistance, 1);
+
+    static const float focalLength = 3.30f; // mm
+    ADD_OR_SIZE(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
+            &focalLength, 1);
+    static const float aperture = 2.8f;
+    ADD_OR_SIZE(ANDROID_LENS_INFO_AVAILABLE_APERTURES,
+            &aperture, 1);
+    static const float filterDensity = 0;
+    ADD_OR_SIZE(ANDROID_LENS_INFO_AVAILABLE_FILTER_DENSITIES,
+            &filterDensity, 1);
+    static const uint8_t availableOpticalStabilization =
+            ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
+    ADD_OR_SIZE(ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
+            &availableOpticalStabilization, 1);
+
+    static const int32_t lensShadingMapSize[] = {1, 1};
+    ADD_OR_SIZE(ANDROID_LENS_INFO_SHADING_MAP_SIZE, lensShadingMapSize,
+            sizeof(lensShadingMapSize)/sizeof(int32_t));
+
+    static const float lensShadingMap[3 * 1 * 1 ] =
+            { 1.f, 1.f, 1.f };
+    ADD_OR_SIZE(ANDROID_LENS_INFO_SHADING_MAP, lensShadingMap,
+            sizeof(lensShadingMap)/sizeof(float));
+
+    // Identity transform
+    static const int32_t geometricCorrectionMapSize[] = {2, 2};
+    ADD_OR_SIZE(ANDROID_LENS_INFO_GEOMETRIC_CORRECTION_MAP_SIZE,
+            geometricCorrectionMapSize,
+            sizeof(geometricCorrectionMapSize)/sizeof(int32_t));
+
+    static const float geometricCorrectionMap[2 * 3 * 2 * 2] = {
+            0.f, 0.f,  0.f, 0.f,  0.f, 0.f,
+            1.f, 0.f,  1.f, 0.f,  1.f, 0.f,
+            0.f, 1.f,  0.f, 1.f,  0.f, 1.f,
+            1.f, 1.f,  1.f, 1.f,  1.f, 1.f};
+    ADD_OR_SIZE(ANDROID_LENS_INFO_GEOMETRIC_CORRECTION_MAP,
+            geometricCorrectionMap,
+            sizeof(geometricCorrectionMap)/sizeof(float));
+
+    int32_t lensFacing = mFacingBack ?
+            ANDROID_LENS_FACING_BACK : ANDROID_LENS_FACING_FRONT;
+    ADD_OR_SIZE(ANDROID_LENS_FACING, &lensFacing, 1);
+
+    float lensPosition[3];
+    if (mFacingBack) {
+        // Back-facing camera is center-top on device
+        lensPosition[0] = 0;
+        lensPosition[1] = 20;
+        lensPosition[2] = -5;
+    } else {
+        // Front-facing camera is center-right on device
+        lensPosition[0] = 20;
+        lensPosition[1] = 20;
+        lensPosition[2] = 0;
+    }
+    ADD_OR_SIZE(ANDROID_LENS_POSITION, lensPosition, sizeof(lensPosition)/
+            sizeof(float));
+
+    // android.sensor
+
+    ADD_OR_SIZE(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
+            Sensor::kExposureTimeRange, 2);
+
+    ADD_OR_SIZE(ANDROID_SENSOR_INFO_MAX_FRAME_DURATION,
+            &Sensor::kFrameDurationRange[1], 1);
+
+    ADD_OR_SIZE(ANDROID_SENSOR_INFO_AVAILABLE_SENSITIVITIES,
+            Sensor::kAvailableSensitivities,
+            sizeof(Sensor::kAvailableSensitivities)
+            /sizeof(uint32_t));
+
+    ADD_OR_SIZE(ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
+            &Sensor::kColorFilterArrangement, 1);
+
+    static const float sensorPhysicalSize[2] = {3.20f, 2.40f}; // mm
+    ADD_OR_SIZE(ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
+            sensorPhysicalSize, 2);
+
+    ADD_OR_SIZE(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
+            Sensor::kResolution, 2);
+
+    ADD_OR_SIZE(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
+            Sensor::kResolution, 2);
+
+    ADD_OR_SIZE(ANDROID_SENSOR_INFO_WHITE_LEVEL,
+            &Sensor::kMaxRawValue, 1);
+
+    static const int32_t blackLevelPattern[4] = {
+            Sensor::kBlackLevel, Sensor::kBlackLevel,
+            Sensor::kBlackLevel, Sensor::kBlackLevel
+    };
+    ADD_OR_SIZE(ANDROID_SENSOR_BLACK_LEVEL_PATTERN,
+            blackLevelPattern, sizeof(blackLevelPattern)/sizeof(int32_t));
+
+    //TODO: sensor color calibration fields
+
+    // android.flash
+    static const uint8_t flashAvailable = 0;
+    ADD_OR_SIZE(ANDROID_FLASH_INFO_AVAILABLE, &flashAvailable, 1);
+
+    static const int64_t flashChargeDuration = 0;
+    ADD_OR_SIZE(ANDROID_FLASH_INFO_CHARGE_DURATION, &flashChargeDuration, 1);
+
+    // android.tonemap
+
+    static const int32_t tonemapCurvePoints = 128;
+    ADD_OR_SIZE(ANDROID_TONEMAP_MAX_CURVE_POINTS, &tonemapCurvePoints, 1);
+
+    // android.scaler
+
+    ADD_OR_SIZE(ANDROID_SCALER_AVAILABLE_FORMATS,
+            kAvailableFormats,
+            sizeof(kAvailableFormats)/sizeof(uint32_t));
+
+    ADD_OR_SIZE(ANDROID_SCALER_AVAILABLE_RAW_SIZES,
+            kAvailableRawSizes,
+            sizeof(kAvailableRawSizes)/sizeof(uint32_t));
+
+    ADD_OR_SIZE(ANDROID_SCALER_AVAILABLE_RAW_MIN_DURATIONS,
+            kAvailableRawMinDurations,
+            sizeof(kAvailableRawMinDurations)/sizeof(uint64_t));
+
+    if (mFacingBack) {
+        ADD_OR_SIZE(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES,
+                kAvailableProcessedSizesBack,
+                sizeof(kAvailableProcessedSizesBack)/sizeof(uint32_t));
+    } else {
+        ADD_OR_SIZE(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES,
+                kAvailableProcessedSizesFront,
+                sizeof(kAvailableProcessedSizesFront)/sizeof(uint32_t));
+    }
+
+    ADD_OR_SIZE(ANDROID_SCALER_AVAILABLE_PROCESSED_MIN_DURATIONS,
+            kAvailableProcessedMinDurations,
+            sizeof(kAvailableProcessedMinDurations)/sizeof(uint64_t));
+
+    if (mFacingBack) {
+        ADD_OR_SIZE(ANDROID_SCALER_AVAILABLE_JPEG_SIZES,
+                kAvailableJpegSizesBack,
+                sizeof(kAvailableJpegSizesBack)/sizeof(uint32_t));
+    } else {
+        ADD_OR_SIZE(ANDROID_SCALER_AVAILABLE_JPEG_SIZES,
+                kAvailableJpegSizesFront,
+                sizeof(kAvailableJpegSizesFront)/sizeof(uint32_t));
+    }
+
+    ADD_OR_SIZE(ANDROID_SCALER_AVAILABLE_JPEG_MIN_DURATIONS,
+            kAvailableJpegMinDurations,
+            sizeof(kAvailableJpegMinDurations)/sizeof(uint64_t));
+
+    static const float maxZoom = 10;
+    ADD_OR_SIZE(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
+            &maxZoom, 1);
+
+    // android.jpeg
+
+    static const int32_t jpegThumbnailSizes[] = {
+            0, 0,
+            160, 120,
+            320, 240
+     };
+    ADD_OR_SIZE(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
+            jpegThumbnailSizes, sizeof(jpegThumbnailSizes)/sizeof(int32_t));
+
+    static const int32_t jpegMaxSize = JpegCompressor::kMaxJpegSize;
+    ADD_OR_SIZE(ANDROID_JPEG_MAX_SIZE, &jpegMaxSize, 1);
+
+    // android.stats
+
+    static const uint8_t availableFaceDetectModes[] = {
+        ANDROID_STATISTICS_FACE_DETECT_MODE_OFF,
+        ANDROID_STATISTICS_FACE_DETECT_MODE_SIMPLE,
+        ANDROID_STATISTICS_FACE_DETECT_MODE_FULL
+    };
+
+    ADD_OR_SIZE(ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
+            availableFaceDetectModes,
+            sizeof(availableFaceDetectModes));
+
+    static const int32_t maxFaceCount = 8;
+    ADD_OR_SIZE(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
+            &maxFaceCount, 1);
+
+    static const int32_t histogramSize = 64;
+    ADD_OR_SIZE(ANDROID_STATISTICS_INFO_HISTOGRAM_BUCKET_COUNT,
+            &histogramSize, 1);
+
+    static const int32_t maxHistogramCount = 1000;
+    ADD_OR_SIZE(ANDROID_STATISTICS_INFO_MAX_HISTOGRAM_COUNT,
+            &maxHistogramCount, 1);
+
+    static const int32_t sharpnessMapSize[2] = {64, 64};
+    ADD_OR_SIZE(ANDROID_STATISTICS_INFO_SHARPNESS_MAP_SIZE,
+            sharpnessMapSize, sizeof(sharpnessMapSize)/sizeof(int32_t));
+
+    static const int32_t maxSharpnessMapValue = 1000;
+    ADD_OR_SIZE(ANDROID_STATISTICS_INFO_MAX_SHARPNESS_MAP_VALUE,
+            &maxSharpnessMapValue, 1);
+
+    // android.control
+
+    static const uint8_t availableSceneModes[] = {
+            ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED
+    };
+    ADD_OR_SIZE(ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
+            availableSceneModes, sizeof(availableSceneModes));
+
+    static const uint8_t availableEffects[] = {
+            ANDROID_CONTROL_EFFECT_MODE_OFF
+    };
+    ADD_OR_SIZE(ANDROID_CONTROL_AVAILABLE_EFFECTS,
+            availableEffects, sizeof(availableEffects));
+
+    int32_t max3aRegions = 0;
+    ADD_OR_SIZE(ANDROID_CONTROL_MAX_REGIONS,
+            &max3aRegions, 1);
+
+    static const uint8_t availableAeModes[] = {
+            ANDROID_CONTROL_AE_MODE_OFF,
+            ANDROID_CONTROL_AE_MODE_ON
+    };
+    ADD_OR_SIZE(ANDROID_CONTROL_AE_AVAILABLE_MODES,
+            availableAeModes, sizeof(availableAeModes));
+
+    static const camera_metadata_rational exposureCompensationStep = {
+            1, 3
+    };
+    ADD_OR_SIZE(ANDROID_CONTROL_AE_COMPENSATION_STEP,
+            &exposureCompensationStep, 1);
+
+    int32_t exposureCompensationRange[] = {-9, 9};
+    ADD_OR_SIZE(ANDROID_CONTROL_AE_COMPENSATION_RANGE,
+            exposureCompensationRange,
+            sizeof(exposureCompensationRange)/sizeof(int32_t));
+
+    static const int32_t availableTargetFpsRanges[] = {
+            5, 30, 15, 30
+    };
+    ADD_OR_SIZE(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
+            availableTargetFpsRanges,
+            sizeof(availableTargetFpsRanges)/sizeof(int32_t));
+
+    static const uint8_t availableAntibandingModes[] = {
+            ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF,
+            ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO
+    };
+    ADD_OR_SIZE(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
+            availableAntibandingModes, sizeof(availableAntibandingModes));
+
+    static const uint8_t availableAwbModes[] = {
+            ANDROID_CONTROL_AWB_MODE_OFF,
+            ANDROID_CONTROL_AWB_MODE_AUTO,
+            ANDROID_CONTROL_AWB_MODE_INCANDESCENT,
+            ANDROID_CONTROL_AWB_MODE_FLUORESCENT,
+            ANDROID_CONTROL_AWB_MODE_DAYLIGHT,
+            ANDROID_CONTROL_AWB_MODE_SHADE
+    };
+    ADD_OR_SIZE(ANDROID_CONTROL_AWB_AVAILABLE_MODES,
+            availableAwbModes, sizeof(availableAwbModes));
+
+    static const uint8_t availableAfModesBack[] = {
+            ANDROID_CONTROL_AF_MODE_OFF,
+            ANDROID_CONTROL_AF_MODE_AUTO,
+            ANDROID_CONTROL_AF_MODE_MACRO,
+            ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO,
+            ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE
+    };
+
+    static const uint8_t availableAfModesFront[] = {
+            ANDROID_CONTROL_AF_MODE_OFF
+    };
+
+    if (mFacingBack) {
+        ADD_OR_SIZE(ANDROID_CONTROL_AF_AVAILABLE_MODES,
+                    availableAfModesBack, sizeof(availableAfModesBack));
+    } else {
+        ADD_OR_SIZE(ANDROID_CONTROL_AF_AVAILABLE_MODES,
+                    availableAfModesFront, sizeof(availableAfModesFront));
+    }
+
+    static const uint8_t availableVstabModes[] = {
+            ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF
+    };
+    ADD_OR_SIZE(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
+            availableVstabModes, sizeof(availableVstabModes));
+
+#undef ADD_OR_SIZE
+    /** Allocate metadata if sizing */
+    if (sizeRequest) {
+        ALOGV("Allocating %d entries, %d extra bytes for "
+                "static camera info",
+                entryCount, dataCount);
+        *info = allocate_camera_metadata(entryCount, dataCount);
+        if (*info == NULL) {
+            ALOGE("Unable to allocate camera static info"
+                    "(%d entries, %d bytes extra data)",
+                    entryCount, dataCount);
+            return NO_MEMORY;
+        }
+    }
+    return OK;
+}
+
+status_t EmulatedFakeCamera2::constructDefaultRequest(
+        int request_template,
+        camera_metadata_t **request,
+        bool sizeRequest) const {
+
+    size_t entryCount = 0;
+    size_t dataCount = 0;
+    status_t ret;
+
+#define ADD_OR_SIZE( tag, data, count ) \
+    if ( ( ret = addOrSize(*request, sizeRequest, &entryCount, &dataCount, \
+            tag, data, count) ) != OK ) return ret
+
+    /** android.request */
+
+    static const uint8_t requestType = ANDROID_REQUEST_TYPE_CAPTURE;
+    ADD_OR_SIZE(ANDROID_REQUEST_TYPE, &requestType, 1);
+
+    static const uint8_t metadataMode = ANDROID_REQUEST_METADATA_MODE_FULL;
+    ADD_OR_SIZE(ANDROID_REQUEST_METADATA_MODE, &metadataMode, 1);
+
+    static const int32_t id = 0;
+    ADD_OR_SIZE(ANDROID_REQUEST_ID, &id, 1);
+
+    static const int32_t frameCount = 0;
+    ADD_OR_SIZE(ANDROID_REQUEST_FRAME_COUNT, &frameCount, 1);
+
+    // OUTPUT_STREAMS set by user
+    entryCount += 1;
+    dataCount += 5; // TODO: Should be maximum stream number
+
+    /** android.lens */
+
+    static const float focusDistance = 0;
+    ADD_OR_SIZE(ANDROID_LENS_FOCUS_DISTANCE, &focusDistance, 1);
+
+    static const float aperture = 2.8f;
+    ADD_OR_SIZE(ANDROID_LENS_APERTURE, &aperture, 1);
+
+    static const float focalLength = 5.0f;
+    ADD_OR_SIZE(ANDROID_LENS_FOCAL_LENGTH, &focalLength, 1);
+
+    static const float filterDensity = 0;
+    ADD_OR_SIZE(ANDROID_LENS_FILTER_DENSITY, &filterDensity, 1);
+
+    static const uint8_t opticalStabilizationMode =
+            ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
+    ADD_OR_SIZE(ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
+            &opticalStabilizationMode, 1);
+
+    // FOCUS_RANGE set only in frame
+
+    /** android.sensor */
+
+    static const int64_t exposureTime = 10 * MSEC;
+    ADD_OR_SIZE(ANDROID_SENSOR_EXPOSURE_TIME, &exposureTime, 1);
+
+    static const int64_t frameDuration = 33333333L; // 1/30 s
+    ADD_OR_SIZE(ANDROID_SENSOR_FRAME_DURATION, &frameDuration, 1);
+
+    static const int32_t sensitivity = 100;
+    ADD_OR_SIZE(ANDROID_SENSOR_SENSITIVITY, &sensitivity, 1);
+
+    // TIMESTAMP set only in frame
+
+    /** android.flash */
+
+    static const uint8_t flashMode = ANDROID_FLASH_MODE_OFF;
+    ADD_OR_SIZE(ANDROID_FLASH_MODE, &flashMode, 1);
+
+    static const uint8_t flashPower = 10;
+    ADD_OR_SIZE(ANDROID_FLASH_FIRING_POWER, &flashPower, 1);
+
+    static const int64_t firingTime = 0;
+    ADD_OR_SIZE(ANDROID_FLASH_FIRING_TIME, &firingTime, 1);
+
+    /** Processing block modes */
+    uint8_t hotPixelMode = 0;
+    uint8_t demosaicMode = 0;
+    uint8_t noiseMode = 0;
+    uint8_t shadingMode = 0;
+    uint8_t geometricMode = 0;
+    uint8_t colorMode = 0;
+    uint8_t tonemapMode = 0;
+    uint8_t edgeMode = 0;
+    switch (request_template) {
+      case CAMERA2_TEMPLATE_STILL_CAPTURE:
+        // fall-through
+      case CAMERA2_TEMPLATE_VIDEO_SNAPSHOT:
+        // fall-through
+      case CAMERA2_TEMPLATE_ZERO_SHUTTER_LAG:
+        hotPixelMode = ANDROID_HOT_PIXEL_MODE_HIGH_QUALITY;
+        demosaicMode = ANDROID_DEMOSAIC_MODE_HIGH_QUALITY;
+        noiseMode = ANDROID_NOISE_REDUCTION_MODE_HIGH_QUALITY;
+        shadingMode = ANDROID_SHADING_MODE_HIGH_QUALITY;
+        geometricMode = ANDROID_GEOMETRIC_MODE_HIGH_QUALITY;
+        colorMode = ANDROID_COLOR_CORRECTION_MODE_HIGH_QUALITY;
+        tonemapMode = ANDROID_TONEMAP_MODE_HIGH_QUALITY;
+        edgeMode = ANDROID_EDGE_MODE_HIGH_QUALITY;
+        break;
+      case CAMERA2_TEMPLATE_PREVIEW:
+        // fall-through
+      case CAMERA2_TEMPLATE_VIDEO_RECORD:
+        // fall-through
+      default:
+        hotPixelMode = ANDROID_HOT_PIXEL_MODE_FAST;
+        demosaicMode = ANDROID_DEMOSAIC_MODE_FAST;
+        noiseMode = ANDROID_NOISE_REDUCTION_MODE_FAST;
+        shadingMode = ANDROID_SHADING_MODE_FAST;
+        geometricMode = ANDROID_GEOMETRIC_MODE_FAST;
+        colorMode = ANDROID_COLOR_CORRECTION_MODE_FAST;
+        tonemapMode = ANDROID_TONEMAP_MODE_FAST;
+        edgeMode = ANDROID_EDGE_MODE_FAST;
+        break;
+    }
+    ADD_OR_SIZE(ANDROID_HOT_PIXEL_MODE, &hotPixelMode, 1);
+    ADD_OR_SIZE(ANDROID_DEMOSAIC_MODE, &demosaicMode, 1);
+    ADD_OR_SIZE(ANDROID_NOISE_REDUCTION_MODE, &noiseMode, 1);
+    ADD_OR_SIZE(ANDROID_SHADING_MODE, &shadingMode, 1);
+    ADD_OR_SIZE(ANDROID_GEOMETRIC_MODE, &geometricMode, 1);
+    ADD_OR_SIZE(ANDROID_COLOR_CORRECTION_MODE, &colorMode, 1);
+    ADD_OR_SIZE(ANDROID_TONEMAP_MODE, &tonemapMode, 1);
+    ADD_OR_SIZE(ANDROID_EDGE_MODE, &edgeMode, 1);
+
+    /** android.noise */
+    static const uint8_t noiseStrength = 5;
+    ADD_OR_SIZE(ANDROID_NOISE_REDUCTION_STRENGTH, &noiseStrength, 1);
+
+    /** android.color */
+    static const float colorTransform[9] = {
+        1.0f, 0.f, 0.f,
+        0.f, 1.f, 0.f,
+        0.f, 0.f, 1.f
+    };
+    ADD_OR_SIZE(ANDROID_COLOR_CORRECTION_TRANSFORM, colorTransform, 9);
+
+    /** android.tonemap */
+    static const float tonemapCurve[4] = {
+        0.f, 0.f,
+        1.f, 1.f
+    };
+    ADD_OR_SIZE(ANDROID_TONEMAP_CURVE_RED, tonemapCurve, 4);
+    ADD_OR_SIZE(ANDROID_TONEMAP_CURVE_GREEN, tonemapCurve, 4);
+    ADD_OR_SIZE(ANDROID_TONEMAP_CURVE_BLUE, tonemapCurve, 4);
+
+    /** android.edge */
+    static const uint8_t edgeStrength = 5;
+    ADD_OR_SIZE(ANDROID_EDGE_STRENGTH, &edgeStrength, 1);
+
+    /** android.scaler */
+    static const int32_t cropRegion[3] = {
+        0, 0, Sensor::kResolution[0]
+    };
+    ADD_OR_SIZE(ANDROID_SCALER_CROP_REGION, cropRegion, 3);
+
+    /** android.jpeg */
+    static const int32_t jpegQuality = 80;
+    ADD_OR_SIZE(ANDROID_JPEG_QUALITY, &jpegQuality, 1);
+
+    static const int32_t thumbnailSize[2] = {
+        640, 480
+    };
+    ADD_OR_SIZE(ANDROID_JPEG_THUMBNAIL_SIZE, thumbnailSize, 2);
+
+    static const int32_t thumbnailQuality = 80;
+    ADD_OR_SIZE(ANDROID_JPEG_THUMBNAIL_QUALITY, &thumbnailQuality, 1);
+
+    static const double gpsCoordinates[2] = {
+        0, 0
+    };
+    ADD_OR_SIZE(ANDROID_JPEG_GPS_COORDINATES, gpsCoordinates, 2);
+
+    static const uint8_t gpsProcessingMethod[32] = "None";
+    ADD_OR_SIZE(ANDROID_JPEG_GPS_PROCESSING_METHOD, gpsProcessingMethod, 32);
+
+    static const int64_t gpsTimestamp = 0;
+    ADD_OR_SIZE(ANDROID_JPEG_GPS_TIMESTAMP, &gpsTimestamp, 1);
+
+    static const int32_t jpegOrientation = 0;
+    ADD_OR_SIZE(ANDROID_JPEG_ORIENTATION, &jpegOrientation, 1);
+
+    /** android.stats */
+
+    static const uint8_t faceDetectMode =
+        ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
+    ADD_OR_SIZE(ANDROID_STATISTICS_FACE_DETECT_MODE, &faceDetectMode, 1);
+
+    static const uint8_t histogramMode = ANDROID_STATISTICS_HISTOGRAM_MODE_OFF;
+    ADD_OR_SIZE(ANDROID_STATISTICS_HISTOGRAM_MODE, &histogramMode, 1);
+
+    static const uint8_t sharpnessMapMode =
+        ANDROID_STATISTICS_SHARPNESS_MAP_MODE_OFF;
+    ADD_OR_SIZE(ANDROID_STATISTICS_SHARPNESS_MAP_MODE, &sharpnessMapMode, 1);
+
+    // faceRectangles, faceScores, faceLandmarks, faceIds, histogram,
+    // sharpnessMap only in frames
+
+    /** android.control */
+
+    uint8_t controlIntent = 0;
+    switch (request_template) {
+      case CAMERA2_TEMPLATE_PREVIEW:
+        controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
+        break;
+      case CAMERA2_TEMPLATE_STILL_CAPTURE:
+        controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE;
+        break;
+      case CAMERA2_TEMPLATE_VIDEO_RECORD:
+        controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD;
+        break;
+      case CAMERA2_TEMPLATE_VIDEO_SNAPSHOT:
+        controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT;
+        break;
+      case CAMERA2_TEMPLATE_ZERO_SHUTTER_LAG:
+        controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG;
+        break;
+      default:
+        controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_CUSTOM;
+        break;
+    }
+    ADD_OR_SIZE(ANDROID_CONTROL_CAPTURE_INTENT, &controlIntent, 1);
+
+    static const uint8_t controlMode = ANDROID_CONTROL_MODE_AUTO;
+    ADD_OR_SIZE(ANDROID_CONTROL_MODE, &controlMode, 1);
+
+    static const uint8_t effectMode = ANDROID_CONTROL_EFFECT_MODE_OFF;
+    ADD_OR_SIZE(ANDROID_CONTROL_EFFECT_MODE, &effectMode, 1);
+
+    static const uint8_t sceneMode = ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY;
+    ADD_OR_SIZE(ANDROID_CONTROL_SCENE_MODE, &sceneMode, 1);
+
+    static const uint8_t aeMode = ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH;
+    ADD_OR_SIZE(ANDROID_CONTROL_AE_MODE, &aeMode, 1);
+
+    static const uint8_t aeLock = ANDROID_CONTROL_AE_LOCK_OFF;
+    ADD_OR_SIZE(ANDROID_CONTROL_AE_LOCK, &aeLock, 1);
+
+    static const int32_t controlRegions[5] = {
+        0, 0, Sensor::kResolution[0], Sensor::kResolution[1], 1000
+    };
+    ADD_OR_SIZE(ANDROID_CONTROL_AE_REGIONS, controlRegions, 5);
+
+    static const int32_t aeExpCompensation = 0;
+    ADD_OR_SIZE(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION, &aeExpCompensation, 1);
+
+    static const int32_t aeTargetFpsRange[2] = {
+        10, 30
+    };
+    ADD_OR_SIZE(ANDROID_CONTROL_AE_TARGET_FPS_RANGE, aeTargetFpsRange, 2);
+
+    static const uint8_t aeAntibandingMode =
+            ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO;
+    ADD_OR_SIZE(ANDROID_CONTROL_AE_ANTIBANDING_MODE, &aeAntibandingMode, 1);
+
+    static const uint8_t awbMode =
+            ANDROID_CONTROL_AWB_MODE_AUTO;
+    ADD_OR_SIZE(ANDROID_CONTROL_AWB_MODE, &awbMode, 1);
+
+    static const uint8_t awbLock = ANDROID_CONTROL_AWB_LOCK_OFF;
+    ADD_OR_SIZE(ANDROID_CONTROL_AWB_LOCK, &awbLock, 1);
+
+    ADD_OR_SIZE(ANDROID_CONTROL_AWB_REGIONS, controlRegions, 5);
+
+    uint8_t afMode = 0;
+    switch (request_template) {
+      case CAMERA2_TEMPLATE_PREVIEW:
+        afMode = ANDROID_CONTROL_AF_MODE_AUTO;
+        break;
+      case CAMERA2_TEMPLATE_STILL_CAPTURE:
+        afMode = ANDROID_CONTROL_AF_MODE_AUTO;
+        break;
+      case CAMERA2_TEMPLATE_VIDEO_RECORD:
+        afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO;
+        break;
+      case CAMERA2_TEMPLATE_VIDEO_SNAPSHOT:
+        afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO;
+        break;
+      case CAMERA2_TEMPLATE_ZERO_SHUTTER_LAG:
+        afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE;
+        break;
+      default:
+        afMode = ANDROID_CONTROL_AF_MODE_AUTO;
+        break;
+    }
+    ADD_OR_SIZE(ANDROID_CONTROL_AF_MODE, &afMode, 1);
+
+    ADD_OR_SIZE(ANDROID_CONTROL_AF_REGIONS, controlRegions, 5);
+
+    static const uint8_t vstabMode =
+        ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF;
+    ADD_OR_SIZE(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE, &vstabMode, 1);
+
+    // aeState, awbState, afState only in frame
+
+    /** Allocate metadata if sizing */
+    if (sizeRequest) {
+        ALOGV("Allocating %d entries, %d extra bytes for "
+                "request template type %d",
+                entryCount, dataCount, request_template);
+        *request = allocate_camera_metadata(entryCount, dataCount);
+        if (*request == NULL) {
+            ALOGE("Unable to allocate new request template type %d "
+                    "(%d entries, %d bytes extra data)", request_template,
+                    entryCount, dataCount);
+            return NO_MEMORY;
+        }
+    }
+    return OK;
+#undef ADD_OR_SIZE
+}
+
+status_t EmulatedFakeCamera2::addOrSize(camera_metadata_t *request,
+        bool sizeRequest,
+        size_t *entryCount,
+        size_t *dataCount,
+        uint32_t tag,
+        const void *entryData,
+        size_t entryDataCount) {
+    status_t res;
+    if (!sizeRequest) {
+        return add_camera_metadata_entry(request, tag, entryData,
+                entryDataCount);
+    } else {
+        int type = get_camera_metadata_tag_type(tag);
+        if (type < 0 ) return BAD_VALUE;
+        (*entryCount)++;
+        (*dataCount) += calculate_camera_metadata_entry_data_size(type,
+                entryDataCount);
+        return OK;
+    }
+}
+
+bool EmulatedFakeCamera2::isStreamInUse(uint32_t id) {
+    // Assumes mMutex is locked; otherwise new requests could enter
+    // configureThread while readoutThread is being checked
+
+    // Order of isStreamInUse calls matters
+    if (mConfigureThread->isStreamInUse(id) ||
+            mReadoutThread->isStreamInUse(id) ||
+            mJpegCompressor->isStreamInUse(id) ) {
+        ALOGE("%s: Stream %d is in use in active requests!",
+                __FUNCTION__, id);
+        return true;
+    }
+    return false;
+}
+
+bool EmulatedFakeCamera2::isReprocessStreamInUse(uint32_t id) {
+    // TODO: implement
+    return false;
+}
+
+const Stream& EmulatedFakeCamera2::getStreamInfo(uint32_t streamId) {
+    Mutex::Autolock lock(mMutex);
+
+    return mStreams.valueFor(streamId);
+}
+
+const ReprocessStream& EmulatedFakeCamera2::getReprocessStreamInfo(uint32_t streamId) {
+    Mutex::Autolock lock(mMutex);
+
+    return mReprocessStreams.valueFor(streamId);
+}
+
+};  /* namespace android */
diff --git a/camera/EmulatedFakeCamera2.h b/camera/EmulatedFakeCamera2.h
new file mode 100644
index 0000000..ee47235
--- /dev/null
+++ b/camera/EmulatedFakeCamera2.h
@@ -0,0 +1,424 @@
+/*
+ * Copyright (C) 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.
+ */
+
+#ifndef HW_EMULATOR_CAMERA_EMULATED_FAKE_CAMERA2_H
+#define HW_EMULATOR_CAMERA_EMULATED_FAKE_CAMERA2_H
+
+/*
+ * Contains declaration of a class EmulatedFakeCamera2 that encapsulates
+ * functionality of a fake camera that implements version 2 of the camera device
+ * interface.
+ */
+
+#include "EmulatedCamera2.h"
+#include "fake-pipeline2/Base.h"
+#include "fake-pipeline2/Sensor.h"
+#include "fake-pipeline2/JpegCompressor.h"
+#include <utils/Condition.h>
+#include <utils/KeyedVector.h>
+#include <utils/String8.h>
+#include <utils/String16.h>
+
+namespace android {
+
+/* Encapsulates functionality of an advanced fake camera.  This camera contains
+ * a simple simulation of a scene, sensor, and image processing pipeline.
+ */
+class EmulatedFakeCamera2 : public EmulatedCamera2 {
+public:
+    /* Constructs EmulatedFakeCamera instance. */
+    EmulatedFakeCamera2(int cameraId, bool facingBack, struct hw_module_t* module);
+
+    /* Destructs EmulatedFakeCamera instance. */
+    ~EmulatedFakeCamera2();
+
+    /****************************************************************************
+     * EmulatedCamera2 virtual overrides.
+     ***************************************************************************/
+
+public:
+    /* Initializes EmulatedFakeCamera2 instance. */
+    status_t Initialize();
+
+    /****************************************************************************
+     * Camera Module API and generic hardware device API implementation
+     ***************************************************************************/
+public:
+
+    virtual status_t connectCamera(hw_device_t** device);
+
+    virtual status_t closeCamera();
+
+    virtual status_t getCameraInfo(struct camera_info *info);
+
+    /****************************************************************************
+     * EmulatedCamera2 abstract API implementation.
+     ***************************************************************************/
+protected:
+    /** Request input queue */
+
+    virtual int requestQueueNotify();
+
+    /** Count of requests in flight */
+    virtual int getInProgressCount();
+
+    /** Cancel all captures in flight */
+    //virtual int flushCapturesInProgress();
+
+    /** Construct default request */
+    virtual int constructDefaultRequest(
+            int request_template,
+            camera_metadata_t **request);
+
+    virtual int allocateStream(
+            uint32_t width,
+            uint32_t height,
+            int format,
+            const camera2_stream_ops_t *stream_ops,
+            uint32_t *stream_id,
+            uint32_t *format_actual,
+            uint32_t *usage,
+            uint32_t *max_buffers);
+
+    virtual int registerStreamBuffers(
+            uint32_t stream_id,
+            int num_buffers,
+            buffer_handle_t *buffers);
+
+    virtual int releaseStream(uint32_t stream_id);
+
+    // virtual int allocateReprocessStream(
+    //         uint32_t width,
+    //         uint32_t height,
+    //         uint32_t format,
+    //         const camera2_stream_ops_t *stream_ops,
+    //         uint32_t *stream_id,
+    //         uint32_t *format_actual,
+    //         uint32_t *usage,
+    //         uint32_t *max_buffers);
+
+    virtual int allocateReprocessStreamFromStream(
+            uint32_t output_stream_id,
+            const camera2_stream_in_ops_t *stream_ops,
+            uint32_t *stream_id);
+
+    virtual int releaseReprocessStream(uint32_t stream_id);
+
+    virtual int triggerAction(uint32_t trigger_id,
+            int32_t ext1,
+            int32_t ext2);
+
+    /** Custom tag definitions */
+    virtual const char* getVendorSectionName(uint32_t tag);
+    virtual const char* getVendorTagName(uint32_t tag);
+    virtual int         getVendorTagType(uint32_t tag);
+
+    /** Debug methods */
+
+    virtual int dump(int fd);
+
+public:
+    /****************************************************************************
+     * Utility methods called by configure/readout threads and pipeline
+     ***************************************************************************/
+
+    // Get information about a given stream. Will lock mMutex
+    const Stream &getStreamInfo(uint32_t streamId);
+    const ReprocessStream &getReprocessStreamInfo(uint32_t streamId);
+
+    // Notifies rest of camera subsystem of serious error
+    void signalError();
+
+private:
+    /****************************************************************************
+     * Utility methods
+     ***************************************************************************/
+    /** Construct static camera metadata, two-pass */
+    status_t constructStaticInfo(
+            camera_metadata_t **info,
+            bool sizeRequest) const;
+
+    /** Two-pass implementation of constructDefaultRequest */
+    status_t constructDefaultRequest(
+            int request_template,
+            camera_metadata_t **request,
+            bool sizeRequest) const;
+    /** Helper function for constructDefaultRequest */
+    static status_t addOrSize( camera_metadata_t *request,
+            bool sizeRequest,
+            size_t *entryCount,
+            size_t *dataCount,
+            uint32_t tag,
+            const void *entry_data,
+            size_t entry_count);
+
+    /** Determine if the stream id is listed in any currently-in-flight
+     * requests. Assumes mMutex is locked */
+    bool isStreamInUse(uint32_t streamId);
+
+    /** Determine if the reprocess stream id is listed in any
+     * currently-in-flight requests. Assumes mMutex is locked */
+    bool isReprocessStreamInUse(uint32_t streamId);
+
+    /****************************************************************************
+     * Pipeline controller threads
+     ***************************************************************************/
+
+    class ConfigureThread: public Thread {
+      public:
+        ConfigureThread(EmulatedFakeCamera2 *parent);
+        ~ConfigureThread();
+
+        status_t waitUntilRunning();
+        status_t newRequestAvailable();
+        status_t readyToRun();
+
+        bool isStreamInUse(uint32_t id);
+        int getInProgressCount();
+      private:
+        EmulatedFakeCamera2 *mParent;
+        static const nsecs_t kWaitPerLoop = 10000000L; // 10 ms
+
+        bool mRunning;
+        bool threadLoop();
+
+        bool setupCapture();
+        bool setupReprocess();
+
+        bool configureNextCapture();
+        bool configureNextReprocess();
+
+        bool getBuffers();
+
+        Mutex mInputMutex; // Protects mActive, mRequestCount
+        Condition mInputSignal;
+        bool mActive; // Whether we're waiting for input requests or actively
+                      // working on them
+        size_t mRequestCount;
+
+        camera_metadata_t *mRequest;
+
+        Mutex mInternalsMutex; // Lock before accessing below members.
+        bool    mWaitingForReadout;
+        bool    mNextNeedsJpeg;
+        bool    mNextIsCapture;
+        int32_t mNextFrameNumber;
+        int64_t mNextExposureTime;
+        int64_t mNextFrameDuration;
+        int32_t mNextSensitivity;
+        Buffers *mNextBuffers;
+    };
+
+    class ReadoutThread: public Thread {
+      public:
+        ReadoutThread(EmulatedFakeCamera2 *parent);
+        ~ReadoutThread();
+
+        status_t readyToRun();
+
+        // Input
+        status_t waitUntilRunning();
+        bool waitForReady(nsecs_t timeout);
+        void setNextOperation(bool isCapture,
+                camera_metadata_t *request,
+                Buffers *buffers);
+        bool isStreamInUse(uint32_t id);
+        int getInProgressCount();
+      private:
+        EmulatedFakeCamera2 *mParent;
+
+        bool mRunning;
+        bool threadLoop();
+
+        bool readyForNextCapture();
+        status_t collectStatisticsMetadata(camera_metadata_t *frame);
+
+        // Inputs
+        Mutex mInputMutex; // Protects mActive, mInFlightQueue, mRequestCount
+        Condition mInputSignal;
+        Condition mReadySignal;
+
+        bool mActive;
+
+        static const int kInFlightQueueSize = 4;
+        struct InFlightQueue {
+            bool isCapture;
+            camera_metadata_t *request;
+            Buffers *buffers;
+        } *mInFlightQueue;
+
+        size_t mInFlightHead;
+        size_t mInFlightTail;
+
+        size_t mRequestCount;
+
+        // Internals
+        Mutex mInternalsMutex;
+
+        bool mIsCapture;
+        camera_metadata_t *mRequest;
+        Buffers *mBuffers;
+
+    };
+
+    // 3A management thread (auto-exposure, focus, white balance)
+    class ControlThread: public Thread {
+      public:
+        ControlThread(EmulatedFakeCamera2 *parent);
+        ~ControlThread();
+
+        status_t readyToRun();
+
+        status_t waitUntilRunning();
+
+        // Interpret request's control parameters and override
+        // capture settings as needed
+        status_t processRequest(camera_metadata_t *request);
+
+        status_t triggerAction(uint32_t msgType,
+                int32_t ext1, int32_t ext2);
+      private:
+        ControlThread(const ControlThread &t);
+        ControlThread& operator=(const ControlThread &t);
+
+        // Constants controlling fake 3A behavior
+        static const nsecs_t kControlCycleDelay;
+        static const nsecs_t kMinAfDuration;
+        static const nsecs_t kMaxAfDuration;
+        static const float kAfSuccessRate;
+        static const float kContinuousAfStartRate;
+
+        static const float kAeScanStartRate;
+        static const nsecs_t kMinAeDuration;
+        static const nsecs_t kMaxAeDuration;
+        static const nsecs_t kMinPrecaptureAeDuration;
+        static const nsecs_t kMaxPrecaptureAeDuration;
+
+        static const nsecs_t kNormalExposureTime;
+        static const nsecs_t kExposureJump;
+        static const nsecs_t kMinExposureTime;
+
+        EmulatedFakeCamera2 *mParent;
+
+        bool mRunning;
+        bool threadLoop();
+
+        Mutex mInputMutex; // Protects input methods
+        Condition mInputSignal;
+
+        // Trigger notifications
+        bool mStartAf;
+        bool mCancelAf;
+        bool mStartPrecapture;
+
+        // Latest state for 3A request fields
+        uint8_t mControlMode;
+
+        uint8_t mEffectMode;
+        uint8_t mSceneMode;
+
+        uint8_t mAfMode;
+        bool mAfModeChange;
+
+        uint8_t mAwbMode;
+        uint8_t mAeMode;
+
+        // Latest trigger IDs
+        int32_t mAfTriggerId;
+        int32_t mPrecaptureTriggerId;
+
+        // Current state for 3A algorithms
+        uint8_t mAfState;
+        uint8_t mAeState;
+        uint8_t mAwbState;
+        bool    mAeLock;
+
+        // Current control parameters
+        nsecs_t mExposureTime;
+
+        // Private to threadLoop and its utility methods
+
+        nsecs_t mAfScanDuration;
+        nsecs_t mAeScanDuration;
+        bool mLockAfterPassiveScan;
+
+        // Utility methods for AF
+        int processAfTrigger(uint8_t afMode, uint8_t afState);
+        int maybeStartAfScan(uint8_t afMode, uint8_t afState);
+        int updateAfScan(uint8_t afMode, uint8_t afState, nsecs_t *maxSleep);
+        void updateAfState(uint8_t newState, int32_t triggerId);
+
+        // Utility methods for precapture trigger
+        int processPrecaptureTrigger(uint8_t aeMode, uint8_t aeState);
+        int maybeStartAeScan(uint8_t aeMode, bool aeLock, uint8_t aeState);
+        int updateAeScan(uint8_t aeMode, bool aeLock, uint8_t aeState,
+                nsecs_t *maxSleep);
+        void updateAeState(uint8_t newState, int32_t triggerId);
+    };
+
+    /****************************************************************************
+     * Static configuration information
+     ***************************************************************************/
+private:
+    static const uint32_t kMaxRawStreamCount = 1;
+    static const uint32_t kMaxProcessedStreamCount = 3;
+    static const uint32_t kMaxJpegStreamCount = 1;
+    static const uint32_t kMaxReprocessStreamCount = 2;
+    static const uint32_t kMaxBufferCount = 4;
+    static const uint32_t kAvailableFormats[];
+    static const uint32_t kAvailableRawSizes[];
+    static const uint64_t kAvailableRawMinDurations[];
+    static const uint32_t kAvailableProcessedSizesBack[];
+    static const uint32_t kAvailableProcessedSizesFront[];
+    static const uint64_t kAvailableProcessedMinDurations[];
+    static const uint32_t kAvailableJpegSizesBack[];
+    static const uint32_t kAvailableJpegSizesFront[];
+    static const uint64_t kAvailableJpegMinDurations[];
+
+    /****************************************************************************
+     * Data members.
+     ***************************************************************************/
+
+protected:
+    /* Facing back (true) or front (false) switch. */
+    bool mFacingBack;
+
+private:
+    /** Stream manipulation */
+    uint32_t mNextStreamId;
+    uint32_t mRawStreamCount;
+    uint32_t mProcessedStreamCount;
+    uint32_t mJpegStreamCount;
+
+    uint32_t mNextReprocessStreamId;
+    uint32_t mReprocessStreamCount;
+
+    KeyedVector<uint32_t, Stream> mStreams;
+    KeyedVector<uint32_t, ReprocessStream> mReprocessStreams;
+
+    /** Simulated hardware interfaces */
+    sp<Sensor> mSensor;
+    sp<JpegCompressor> mJpegCompressor;
+
+    /** Pipeline control threads */
+    sp<ConfigureThread> mConfigureThread;
+    sp<ReadoutThread>   mReadoutThread;
+    sp<ControlThread>   mControlThread;
+};
+
+}; /* namespace android */
+
+#endif  /* HW_EMULATOR_CAMERA_EMULATED_FAKE_CAMERA2_H */
diff --git a/camera/EmulatedFakeCameraDevice.cpp b/camera/EmulatedFakeCameraDevice.cpp
new file mode 100755
index 0000000..0bc4c54
--- /dev/null
+++ b/camera/EmulatedFakeCameraDevice.cpp
@@ -0,0 +1,430 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+/*
+ * Contains implementation of a class EmulatedFakeCameraDevice that encapsulates
+ * fake camera device.
+ */
+
+#define LOG_NDEBUG 0
+#define LOG_TAG "EmulatedCamera_FakeDevice"
+#include <cutils/log.h>
+#include "EmulatedFakeCamera.h"
+#include "EmulatedFakeCameraDevice.h"
+
+namespace android {
+
+EmulatedFakeCameraDevice::EmulatedFakeCameraDevice(EmulatedFakeCamera* camera_hal)
+    : EmulatedCameraDevice(camera_hal),
+      mBlackYUV(kBlack32),
+      mWhiteYUV(kWhite32),
+      mRedYUV(kRed8),
+      mGreenYUV(kGreen8),
+      mBlueYUV(kBlue8),
+      mLastRedrawn(0),
+      mCheckX(0),
+      mCheckY(0),
+      mCcounter(0)
+#if EFCD_ROTATE_FRAME
+      , mLastRotatedAt(0),
+        mCurrentFrameType(0),
+        mCurrentColor(&mWhiteYUV)
+#endif  // EFCD_ROTATE_FRAME
+{
+    // Makes the image with the original exposure compensation darker.
+    // So the effects of changing the exposure compensation can be seen.
+    mBlackYUV.Y = mBlackYUV.Y / 2;
+    mWhiteYUV.Y = mWhiteYUV.Y / 2;
+    mRedYUV.Y = mRedYUV.Y / 2;
+    mGreenYUV.Y = mGreenYUV.Y / 2;
+    mBlueYUV.Y = mBlueYUV.Y / 2;
+}
+
+EmulatedFakeCameraDevice::~EmulatedFakeCameraDevice()
+{
+}
+
+/****************************************************************************
+ * Emulated camera device abstract interface implementation.
+ ***************************************************************************/
+
+status_t EmulatedFakeCameraDevice::connectDevice()
+{
+    ALOGV("%s", __FUNCTION__);
+
+    Mutex::Autolock locker(&mObjectLock);
+    if (!isInitialized()) {
+        ALOGE("%s: Fake camera device is not initialized.", __FUNCTION__);
+        return EINVAL;
+    }
+    if (isConnected()) {
+        ALOGW("%s: Fake camera device is already connected.", __FUNCTION__);
+        return NO_ERROR;
+    }
+
+    /* There is no device to connect to. */
+    mState = ECDS_CONNECTED;
+
+    return NO_ERROR;
+}
+
+status_t EmulatedFakeCameraDevice::disconnectDevice()
+{
+    ALOGV("%s", __FUNCTION__);
+
+    Mutex::Autolock locker(&mObjectLock);
+    if (!isConnected()) {
+        ALOGW("%s: Fake camera device is already disconnected.", __FUNCTION__);
+        return NO_ERROR;
+    }
+    if (isStarted()) {
+        ALOGE("%s: Cannot disconnect from the started device.", __FUNCTION__);
+        return EINVAL;
+    }
+
+    /* There is no device to disconnect from. */
+    mState = ECDS_INITIALIZED;
+
+    return NO_ERROR;
+}
+
+status_t EmulatedFakeCameraDevice::startDevice(int width,
+                                               int height,
+                                               uint32_t pix_fmt)
+{
+    ALOGV("%s", __FUNCTION__);
+
+    Mutex::Autolock locker(&mObjectLock);
+    if (!isConnected()) {
+        ALOGE("%s: Fake camera device is not connected.", __FUNCTION__);
+        return EINVAL;
+    }
+    if (isStarted()) {
+        ALOGE("%s: Fake camera device is already started.", __FUNCTION__);
+        return EINVAL;
+    }
+
+    /* Initialize the base class. */
+    const status_t res =
+        EmulatedCameraDevice::commonStartDevice(width, height, pix_fmt);
+    if (res == NO_ERROR) {
+        /* Calculate U/V panes inside the framebuffer. */
+        switch (mPixelFormat) {
+            case V4L2_PIX_FMT_YVU420:
+                mFrameV = mCurrentFrame + mTotalPixels;
+                mFrameU = mFrameU + mTotalPixels / 4;
+                mUVStep = 1;
+                mUVTotalNum = mTotalPixels / 4;
+                break;
+
+            case V4L2_PIX_FMT_YUV420:
+                mFrameU = mCurrentFrame + mTotalPixels;
+                mFrameV = mFrameU + mTotalPixels / 4;
+                mUVStep = 1;
+                mUVTotalNum = mTotalPixels / 4;
+                break;
+
+            case V4L2_PIX_FMT_NV21:
+                /* Interleaved UV pane, V first. */
+                mFrameV = mCurrentFrame + mTotalPixels;
+                mFrameU = mFrameV + 1;
+                mUVStep = 2;
+                mUVTotalNum = mTotalPixels / 4;
+                break;
+
+            case V4L2_PIX_FMT_NV12:
+                /* Interleaved UV pane, U first. */
+                mFrameU = mCurrentFrame + mTotalPixels;
+                mFrameV = mFrameU + 1;
+                mUVStep = 2;
+                mUVTotalNum = mTotalPixels / 4;
+                break;
+
+            default:
+                ALOGE("%s: Unknown pixel format %.4s", __FUNCTION__,
+                     reinterpret_cast<const char*>(&mPixelFormat));
+                return EINVAL;
+        }
+        /* Number of items in a single row inside U/V panes. */
+        mUVInRow = (width / 2) * mUVStep;
+        mState = ECDS_STARTED;
+    } else {
+        ALOGE("%s: commonStartDevice failed", __FUNCTION__);
+    }
+
+    return res;
+}
+
+status_t EmulatedFakeCameraDevice::stopDevice()
+{
+    ALOGV("%s", __FUNCTION__);
+
+    Mutex::Autolock locker(&mObjectLock);
+    if (!isStarted()) {
+        ALOGW("%s: Fake camera device is not started.", __FUNCTION__);
+        return NO_ERROR;
+    }
+
+    mFrameU = mFrameV = NULL;
+    EmulatedCameraDevice::commonStopDevice();
+    mState = ECDS_CONNECTED;
+
+    return NO_ERROR;
+}
+
+/****************************************************************************
+ * Worker thread management overrides.
+ ***************************************************************************/
+
+bool EmulatedFakeCameraDevice::inWorkerThread()
+{
+    /* Wait till FPS timeout expires, or thread exit message is received. */
+    WorkerThread::SelectRes res =
+        getWorkerThread()->Select(-1, 1000000 / mEmulatedFPS);
+    if (res == WorkerThread::EXIT_THREAD) {
+        ALOGV("%s: Worker thread has been terminated.", __FUNCTION__);
+        return false;
+    }
+
+    /* Lets see if we need to generate a new frame. */
+    if ((systemTime(SYSTEM_TIME_MONOTONIC) - mLastRedrawn) >= mRedrawAfter) {
+        /*
+         * Time to generate a new frame.
+         */
+
+#if EFCD_ROTATE_FRAME
+        const int frame_type = rotateFrame();
+        switch (frame_type) {
+            case 0:
+                drawCheckerboard();
+                break;
+            case 1:
+                drawStripes();
+                break;
+            case 2:
+                drawSolid(mCurrentColor);
+                break;
+        }
+#else
+        /* Draw the checker board. */
+        drawCheckerboard();
+
+#endif  // EFCD_ROTATE_FRAME
+
+        mLastRedrawn = systemTime(SYSTEM_TIME_MONOTONIC);
+    }
+
+    /* Timestamp the current frame, and notify the camera HAL about new frame. */
+    mCurFrameTimestamp = systemTime(SYSTEM_TIME_MONOTONIC);
+    mCameraHAL->onNextFrameAvailable(mCurrentFrame, mCurFrameTimestamp, this);
+
+    return true;
+}
+
+/****************************************************************************
+ * Fake camera device private API
+ ***************************************************************************/
+
+void EmulatedFakeCameraDevice::drawCheckerboard()
+{
+    const int size = mFrameWidth / 10;
+    bool black = true;
+
+    if((mCheckX / size) & 1)
+        black = false;
+    if((mCheckY / size) & 1)
+        black = !black;
+
+    int county = mCheckY % size;
+    int checkxremainder = mCheckX % size;
+    uint8_t* Y = mCurrentFrame;
+    uint8_t* U_pos = mFrameU;
+    uint8_t* V_pos = mFrameV;
+    uint8_t* U = U_pos;
+    uint8_t* V = V_pos;
+
+    YUVPixel adjustedWhite = YUVPixel(mWhiteYUV);
+    changeWhiteBalance(adjustedWhite.Y, adjustedWhite.U, adjustedWhite.V);
+
+    for(int y = 0; y < mFrameHeight; y++) {
+        int countx = checkxremainder;
+        bool current = black;
+        for(int x = 0; x < mFrameWidth; x += 2) {
+            if (current) {
+                mBlackYUV.get(Y, U, V);
+            } else {
+                adjustedWhite.get(Y, U, V);
+            }
+            *Y = changeExposure(*Y);
+            Y[1] = *Y;
+            Y += 2; U += mUVStep; V += mUVStep;
+            countx += 2;
+            if(countx >= size) {
+                countx = 0;
+                current = !current;
+            }
+        }
+        if (y & 0x1) {
+            U_pos = U;
+            V_pos = V;
+        } else {
+            U = U_pos;
+            V = V_pos;
+        }
+        if(county++ >= size) {
+            county = 0;
+            black = !black;
+        }
+    }
+    mCheckX += 3;
+    mCheckY++;
+
+    /* Run the square. */
+    int sqx = ((mCcounter * 3) & 255);
+    if(sqx > 128) sqx = 255 - sqx;
+    int sqy = ((mCcounter * 5) & 255);
+    if(sqy > 128) sqy = 255 - sqy;
+    const int sqsize = mFrameWidth / 10;
+    drawSquare(sqx * sqsize / 32, sqy * sqsize / 32, (sqsize * 5) >> 1,
+               (mCcounter & 0x100) ? &mRedYUV : &mGreenYUV);
+    mCcounter++;
+}
+
+void EmulatedFakeCameraDevice::drawSquare(int x,
+                                          int y,
+                                          int size,
+                                          const YUVPixel* color)
+{
+    const int square_xstop = min(mFrameWidth, x + size);
+    const int square_ystop = min(mFrameHeight, y + size);
+    uint8_t* Y_pos = mCurrentFrame + y * mFrameWidth + x;
+
+    YUVPixel adjustedColor = *color;
+    changeWhiteBalance(adjustedColor.Y, adjustedColor.U, adjustedColor.V);
+
+    // Draw the square.
+    for (; y < square_ystop; y++) {
+        const int iUV = (y / 2) * mUVInRow + (x / 2) * mUVStep;
+        uint8_t* sqU = mFrameU + iUV;
+        uint8_t* sqV = mFrameV + iUV;
+        uint8_t* sqY = Y_pos;
+        for (int i = x; i < square_xstop; i += 2) {
+            adjustedColor.get(sqY, sqU, sqV);
+            *sqY = changeExposure(*sqY);
+            sqY[1] = *sqY;
+            sqY += 2; sqU += mUVStep; sqV += mUVStep;
+        }
+        Y_pos += mFrameWidth;
+    }
+}
+
+#if EFCD_ROTATE_FRAME
+
+void EmulatedFakeCameraDevice::drawSolid(YUVPixel* color)
+{
+    YUVPixel adjustedColor = *color;
+    changeWhiteBalance(adjustedColor.Y, adjustedColor.U, adjustedColor.V);
+
+    /* All Ys are the same. */
+    memset(mCurrentFrame, changeExposure(adjustedColor.Y), mTotalPixels);
+
+    /* Fill U, and V panes. */
+    uint8_t* U = mFrameU;
+    uint8_t* V = mFrameV;
+    for (int k = 0; k < mUVTotalNum; k++, U += mUVStep, V += mUVStep) {
+        *U = color->U;
+        *V = color->V;
+    }
+}
+
+void EmulatedFakeCameraDevice::drawStripes()
+{
+    /* Divide frame into 4 stripes. */
+    const int change_color_at = mFrameHeight / 4;
+    const int each_in_row = mUVInRow / mUVStep;
+    uint8_t* pY = mCurrentFrame;
+    for (int y = 0; y < mFrameHeight; y++, pY += mFrameWidth) {
+        /* Select the color. */
+        YUVPixel* color;
+        const int color_index = y / change_color_at;
+        if (color_index == 0) {
+            /* White stripe on top. */
+            color = &mWhiteYUV;
+        } else if (color_index == 1) {
+            /* Then the red stripe. */
+            color = &mRedYUV;
+        } else if (color_index == 2) {
+            /* Then the green stripe. */
+            color = &mGreenYUV;
+        } else {
+            /* And the blue stripe at the bottom. */
+            color = &mBlueYUV;
+        }
+        changeWhiteBalance(color->Y, color->U, color->V);
+
+        /* All Ys at the row are the same. */
+        memset(pY, changeExposure(color->Y), mFrameWidth);
+
+        /* Offset of the current row inside U/V panes. */
+        const int uv_off = (y / 2) * mUVInRow;
+        /* Fill U, and V panes. */
+        uint8_t* U = mFrameU + uv_off;
+        uint8_t* V = mFrameV + uv_off;
+        for (int k = 0; k < each_in_row; k++, U += mUVStep, V += mUVStep) {
+            *U = color->U;
+            *V = color->V;
+        }
+    }
+}
+
+int EmulatedFakeCameraDevice::rotateFrame()
+{
+    if ((systemTime(SYSTEM_TIME_MONOTONIC) - mLastRotatedAt) >= mRotateFreq) {
+        mLastRotatedAt = systemTime(SYSTEM_TIME_MONOTONIC);
+        mCurrentFrameType++;
+        if (mCurrentFrameType > 2) {
+            mCurrentFrameType = 0;
+        }
+        if (mCurrentFrameType == 2) {
+            ALOGD("********** Rotated to the SOLID COLOR frame **********");
+            /* Solid color: lets rotate color too. */
+            if (mCurrentColor == &mWhiteYUV) {
+                ALOGD("----- Painting a solid RED frame -----");
+                mCurrentColor = &mRedYUV;
+            } else if (mCurrentColor == &mRedYUV) {
+                ALOGD("----- Painting a solid GREEN frame -----");
+                mCurrentColor = &mGreenYUV;
+            } else if (mCurrentColor == &mGreenYUV) {
+                ALOGD("----- Painting a solid BLUE frame -----");
+                mCurrentColor = &mBlueYUV;
+            } else {
+                /* Back to white. */
+                ALOGD("----- Painting a solid WHITE frame -----");
+                mCurrentColor = &mWhiteYUV;
+            }
+        } else if (mCurrentFrameType == 0) {
+            ALOGD("********** Rotated to the CHECKERBOARD frame **********");
+        } else if (mCurrentFrameType == 1) {
+            ALOGD("********** Rotated to the STRIPED frame **********");
+        }
+    }
+
+    return mCurrentFrameType;
+}
+
+#endif  // EFCD_ROTATE_FRAME
+
+}; /* namespace android */
diff --git a/camera/EmulatedFakeCameraDevice.h b/camera/EmulatedFakeCameraDevice.h
new file mode 100755
index 0000000..f66f076
--- /dev/null
+++ b/camera/EmulatedFakeCameraDevice.h
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef HW_EMULATOR_CAMERA_EMULATED_FAKE_CAMERA_DEVICE_H
+#define HW_EMULATOR_CAMERA_EMULATED_FAKE_CAMERA_DEVICE_H
+
+/*
+ * Contains declaration of a class EmulatedFakeCameraDevice that encapsulates
+ * a fake camera device.
+ */
+
+#include "Converters.h"
+#include "EmulatedCameraDevice.h"
+
+/* This is used for debugging format / conversion issues. If EFCD_ROTATE_FRAME is
+ * set to 0, the frame content will be always the "checkerboard". Otherwise, if
+ * EFCD_ROTATE_FRAME is set to a non-zero value, the frame content will "rotate"
+ * from a "checkerboard" frame to a "white/red/green/blue stripes" frame, to a
+ * "white/red/green/blue" frame. Frame content rotation helps finding bugs in
+ * format conversions.
+ */
+#define EFCD_ROTATE_FRAME   0
+
+namespace android {
+
+class EmulatedFakeCamera;
+
+/* Encapsulates a fake camera device.
+ * Fake camera device emulates a camera device by providing frames containing
+ * a black and white checker board, moving diagonally towards the 0,0 corner.
+ * There is also a green, or red square that bounces inside the frame, changing
+ * its color when bouncing off the 0,0 corner.
+ */
+class EmulatedFakeCameraDevice : public EmulatedCameraDevice {
+public:
+    /* Constructs EmulatedFakeCameraDevice instance. */
+    explicit EmulatedFakeCameraDevice(EmulatedFakeCamera* camera_hal);
+
+    /* Destructs EmulatedFakeCameraDevice instance. */
+    ~EmulatedFakeCameraDevice();
+
+    /***************************************************************************
+     * Emulated camera device abstract interface implementation.
+     * See declarations of these methods in EmulatedCameraDevice class for
+     * information on each of these methods.
+     **************************************************************************/
+
+public:
+    /* Connects to the camera device.
+     * Since there is no real device to connect to, this method does nothing,
+     * but changes the state.
+     */
+    status_t connectDevice();
+
+    /* Disconnects from the camera device.
+     * Since there is no real device to disconnect from, this method does
+     * nothing, but changes the state.
+     */
+    status_t disconnectDevice();
+
+    /* Starts the camera device. */
+    status_t startDevice(int width, int height, uint32_t pix_fmt);
+
+    /* Stops the camera device. */
+    status_t stopDevice();
+
+    /* Gets current preview fame into provided buffer. */
+    status_t getPreviewFrame(void* buffer);
+
+    /***************************************************************************
+     * Worker thread management overrides.
+     * See declarations of these methods in EmulatedCameraDevice class for
+     * information on each of these methods.
+     **************************************************************************/
+
+protected:
+    /* Implementation of the worker thread routine.
+     * This method simply sleeps for a period of time defined by the FPS property
+     * of the fake camera (simulating frame frequency), and then calls emulated
+     * camera's onNextFrameAvailable method.
+     */
+    bool inWorkerThread();
+
+    /****************************************************************************
+     * Fake camera device private API
+     ***************************************************************************/
+
+private:
+
+    /* Draws a black and white checker board in the current frame buffer. */
+    void drawCheckerboard();
+
+    /* Draws a square of the given color in the current frame buffer.
+     * Param:
+     *  x, y - Coordinates of the top left corner of the square in the buffer.
+     *  size - Size of the square's side.
+     *  color - Square's color.
+     */
+    void drawSquare(int x, int y, int size, const YUVPixel* color);
+
+#if EFCD_ROTATE_FRAME
+    void drawSolid(YUVPixel* color);
+    void drawStripes();
+    int rotateFrame();
+#endif  // EFCD_ROTATE_FRAME
+
+    /****************************************************************************
+     * Fake camera device data members
+     ***************************************************************************/
+
+private:
+    /*
+     * Pixel colors in YUV format used when drawing the checker board.
+     */
+
+    YUVPixel    mBlackYUV;
+    YUVPixel    mWhiteYUV;
+    YUVPixel    mRedYUV;
+    YUVPixel    mGreenYUV;
+    YUVPixel    mBlueYUV;
+
+    /* Last time the frame has been redrawn. */
+    nsecs_t     mLastRedrawn;
+
+    /*
+     * Precalculated values related to U/V panes.
+     */
+
+    /* U pane inside the framebuffer. */
+    uint8_t*    mFrameU;
+
+    /* V pane inside the framebuffer. */
+    uint8_t*    mFrameV;
+
+    /* Defines byte distance between adjacent U, and V values. */
+    int         mUVStep;
+
+    /* Defines number of Us and Vs in a row inside the U/V panes.
+     * Note that if U/V panes are interleaved, this value reflects the total
+     * number of both, Us and Vs in a single row in the interleaved UV pane. */
+    int         mUVInRow;
+
+    /* Total number of each, U, and V elements in the framebuffer. */
+    int         mUVTotalNum;
+
+    /*
+     * Checkerboard drawing related stuff
+     */
+
+    int         mCheckX;
+    int         mCheckY;
+    int         mCcounter;
+
+    /* Emulated FPS (frames per second).
+     * We will emulate 50 FPS. */
+    static const int        mEmulatedFPS = 50;
+
+    /* Defines time (in nanoseconds) between redrawing the checker board.
+     * We will redraw the checker board every 15 milliseconds. */
+    static const nsecs_t    mRedrawAfter = 15000000LL;
+
+#if EFCD_ROTATE_FRAME
+    /* Frame rotation frequency in nanosec (currently - 3 sec) */
+    static const nsecs_t    mRotateFreq = 3000000000LL;
+
+    /* Last time the frame has rotated. */
+    nsecs_t     mLastRotatedAt;
+
+    /* Type of the frame to display in the current rotation:
+     *  0 - Checkerboard.
+     *  1 - White/Red/Green/Blue horisontal stripes
+     *  2 - Solid color. */
+    int         mCurrentFrameType;
+
+    /* Color to use to paint the solid color frame. Colors will rotate between
+     * white, red, gree, and blue each time rotation comes to the solid color
+     * frame. */
+    YUVPixel*   mCurrentColor;
+#endif  // EFCD_ROTATE_FRAME
+};
+
+}; /* namespace android */
+
+#endif  /* HW_EMULATOR_CAMERA_EMULATED_FAKE_CAMERA_DEVICE_H */
diff --git a/camera/EmulatedQemuCamera.cpp b/camera/EmulatedQemuCamera.cpp
new file mode 100755
index 0000000..af1e324
--- /dev/null
+++ b/camera/EmulatedQemuCamera.cpp
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+/*
+ * Contains implementation of a class EmulatedQemuCamera that encapsulates
+ * functionality of an emulated camera connected to the host.
+ */
+
+#define LOG_NDEBUG 0
+#define LOG_TAG "EmulatedCamera_QemuCamera"
+#include <cutils/log.h>
+#include "EmulatedQemuCamera.h"
+#include "EmulatedCameraFactory.h"
+
+namespace android {
+
+EmulatedQemuCamera::EmulatedQemuCamera(int cameraId, struct hw_module_t* module)
+        : EmulatedCamera(cameraId, module),
+          mQemuCameraDevice(this)
+{
+}
+
+EmulatedQemuCamera::~EmulatedQemuCamera()
+{
+}
+
+/****************************************************************************
+ * EmulatedCamera virtual overrides.
+ ***************************************************************************/
+
+status_t EmulatedQemuCamera::Initialize(const char* device_name,
+                                        const char* frame_dims,
+                                        const char* facing_dir)
+{
+    ALOGV("%s:\n   Name=%s\n   Facing '%s'\n   Dimensions=%s",
+         __FUNCTION__, device_name, facing_dir, frame_dims);
+    /* Save dimensions. */
+    mFrameDims = frame_dims;
+
+    /* Initialize camera device. */
+    status_t res = mQemuCameraDevice.Initialize(device_name);
+    if (res != NO_ERROR) {
+        return res;
+    }
+
+    /* Initialize base class. */
+    res = EmulatedCamera::Initialize();
+    if (res != NO_ERROR) {
+        return res;
+    }
+
+    /*
+     * Set customizable parameters.
+     */
+
+    mParameters.set(EmulatedCamera::FACING_KEY, facing_dir);
+    mParameters.set(EmulatedCamera::ORIENTATION_KEY,
+                    gEmulatedCameraFactory.getQemuCameraOrientation());
+    mParameters.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES, frame_dims);
+    mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES, frame_dims);
+
+    /*
+     * Use first dimension reported by the device to set current preview and
+     * picture sizes.
+     */
+
+    char first_dim[128];
+    /* Dimensions are separated with ',' */
+    const char* c = strchr(frame_dims, ',');
+    if (c == NULL) {
+        strncpy(first_dim, frame_dims, sizeof(first_dim));
+        first_dim[sizeof(first_dim)-1] = '\0';
+    } else if (static_cast<size_t>(c - frame_dims) < sizeof(first_dim)) {
+        memcpy(first_dim, frame_dims, c - frame_dims);
+        first_dim[c - frame_dims] = '\0';
+    } else {
+        memcpy(first_dim, frame_dims, sizeof(first_dim));
+        first_dim[sizeof(first_dim)-1] = '\0';
+    }
+
+    /* Width and height are separated with 'x' */
+    char* sep = strchr(first_dim, 'x');
+    if (sep == NULL) {
+        ALOGE("%s: Invalid first dimension format in %s",
+             __FUNCTION__, frame_dims);
+        return EINVAL;
+    }
+
+    *sep = '\0';
+    const int x = atoi(first_dim);
+    const int y = atoi(sep + 1);
+    mParameters.setPreviewSize(x, y);
+    mParameters.setPictureSize(x, y);
+
+    ALOGV("%s: Qemu camera %s is initialized. Current frame is %dx%d",
+         __FUNCTION__, device_name, x, y);
+
+    return NO_ERROR;
+}
+
+EmulatedCameraDevice* EmulatedQemuCamera::getCameraDevice()
+{
+    return &mQemuCameraDevice;
+}
+
+};  /* namespace android */
diff --git a/camera/EmulatedQemuCamera.h b/camera/EmulatedQemuCamera.h
new file mode 100755
index 0000000..1b826c7
--- /dev/null
+++ b/camera/EmulatedQemuCamera.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef HW_EMULATOR_CAMERA_EMULATED_QEMU_CAMERA_H
+#define HW_EMULATOR_CAMERA_EMULATED_QEMU_CAMERA_H
+
+/*
+ * Contains declaration of a class EmulatedQemuCamera that encapsulates
+ * functionality of an emulated camera connected to the host.
+ */
+
+#include "EmulatedCamera.h"
+#include "EmulatedQemuCameraDevice.h"
+
+namespace android {
+
+/* Encapsulates functionality of an emulated camera connected to the host.
+ */
+class EmulatedQemuCamera : public EmulatedCamera {
+public:
+    /* Constructs EmulatedQemuCamera instance. */
+    EmulatedQemuCamera(int cameraId, struct hw_module_t* module);
+
+    /* Destructs EmulatedQemuCamera instance. */
+    ~EmulatedQemuCamera();
+
+    /***************************************************************************
+     * EmulatedCamera virtual overrides.
+     **************************************************************************/
+
+public:
+    /* Initializes EmulatedQemuCamera instance. */
+     status_t Initialize(const char* device_name,
+                         const char* frame_dims,
+                         const char* facing_dir);
+
+    /***************************************************************************
+     * EmulatedCamera abstract API implementation.
+     **************************************************************************/
+
+protected:
+    /* Gets emulated camera device ised by this instance of the emulated camera.
+     */
+    EmulatedCameraDevice* getCameraDevice();
+
+    /***************************************************************************
+     * Data memebers.
+     **************************************************************************/
+
+protected:
+    /* Contained qemu camera device object. */
+    EmulatedQemuCameraDevice    mQemuCameraDevice;
+
+    /* Supported frame dimensions reported by the camera device. */
+    String8                     mFrameDims;
+};
+
+}; /* namespace android */
+
+#endif  /* HW_EMULATOR_CAMERA_EMULATED_QEMU_CAMERA_H */
diff --git a/camera/EmulatedQemuCamera2.cpp b/camera/EmulatedQemuCamera2.cpp
new file mode 100644
index 0000000..2c94f0e
--- /dev/null
+++ b/camera/EmulatedQemuCamera2.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 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.
+ */
+
+/*
+ * Contains implementation of a class EmulatedQemuCamera2 that encapsulates
+ * functionality of a host webcam with further processing to simulate the
+ * capabilities of a v2 camera device.
+ */
+
+#define LOG_NDEBUG 0
+#define LOG_TAG "EmulatedCamera_QemuCamera2"
+#include <cutils/log.h>
+#include <cutils/properties.h>
+#include "EmulatedQemuCamera2.h"
+#include "EmulatedCameraFactory.h"
+
+namespace android {
+
+EmulatedQemuCamera2::EmulatedQemuCamera2(int cameraId,
+        bool facingBack,
+        struct hw_module_t* module)
+        : EmulatedCamera2(cameraId,module),
+          mFacingBack(facingBack)
+{
+    ALOGD("Constructing emulated qemu camera 2 facing %s",
+            facingBack ? "back" : "front");
+}
+
+EmulatedQemuCamera2::~EmulatedQemuCamera2()
+{
+}
+
+/****************************************************************************
+ * Public API overrides
+ ***************************************************************************/
+
+status_t EmulatedQemuCamera2::Initialize()
+{
+    return NO_ERROR;
+}
+
+};  /* namespace android */
diff --git a/camera/EmulatedQemuCamera2.h b/camera/EmulatedQemuCamera2.h
new file mode 100644
index 0000000..520ccce
--- /dev/null
+++ b/camera/EmulatedQemuCamera2.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 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.
+ */
+
+#ifndef HW_EMULATOR_CAMERA_EMULATED_QEMU_CAMERA2_H
+#define HW_EMULATOR_CAMERA_EMULATED_QEMU_CAMERA2_H
+
+/*
+ * Contains declaration of a class EmulatedQemuCamera2 that encapsulates
+ * functionality of a host webcam with added processing to implement version 2
+ * of the camera device interface.
+ */
+
+#include "EmulatedCamera2.h"
+
+namespace android {
+
+/* Encapsulates functionality of an advanced fake camera based on real host camera data.
+ */
+class EmulatedQemuCamera2 : public EmulatedCamera2 {
+public:
+    /* Constructs EmulatedFakeCamera instance. */
+    EmulatedQemuCamera2(int cameraId, bool facingBack, struct hw_module_t* module);
+
+    /* Destructs EmulatedFakeCamera instance. */
+    ~EmulatedQemuCamera2();
+
+    /****************************************************************************
+     * EmulatedCamera2 virtual overrides.
+     ***************************************************************************/
+
+public:
+    /* Initializes EmulatedQemuCamera2 instance. */
+     status_t Initialize();
+
+    /****************************************************************************
+     * EmulatedCamera abstract API implementation.
+     ***************************************************************************/
+
+protected:
+
+    /****************************************************************************
+     * Data memebers.
+     ***************************************************************************/
+
+protected:
+    /* Facing back (true) or front (false) switch. */
+    bool                        mFacingBack;
+
+};
+
+}; /* namespace android */
+
+#endif  /* HW_EMULATOR_CAMERA_EMULATED_QEMU_CAMERA2_H */
diff --git a/camera/EmulatedQemuCameraDevice.cpp b/camera/EmulatedQemuCameraDevice.cpp
new file mode 100755
index 0000000..07837af
--- /dev/null
+++ b/camera/EmulatedQemuCameraDevice.cpp
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+/*
+ * Contains implementation of a class EmulatedQemuCameraDevice that encapsulates
+ * an emulated camera device connected to the host.
+ */
+
+#define LOG_NDEBUG 0
+#define LOG_TAG "EmulatedCamera_QemuDevice"
+#include <cutils/log.h>
+#include "EmulatedQemuCamera.h"
+#include "EmulatedQemuCameraDevice.h"
+
+namespace android {
+
+EmulatedQemuCameraDevice::EmulatedQemuCameraDevice(EmulatedQemuCamera* camera_hal)
+    : EmulatedCameraDevice(camera_hal),
+      mQemuClient(),
+      mPreviewFrame(NULL)
+{
+}
+
+EmulatedQemuCameraDevice::~EmulatedQemuCameraDevice()
+{
+    if (mPreviewFrame != NULL) {
+        delete[] mPreviewFrame;
+    }
+}
+
+/****************************************************************************
+ * Public API
+ ***************************************************************************/
+
+status_t EmulatedQemuCameraDevice::Initialize(const char* device_name)
+{
+    /* Connect to the service. */
+    char connect_str[256];
+    snprintf(connect_str, sizeof(connect_str), "name=%s", device_name);
+    status_t res = mQemuClient.connectClient(connect_str);
+    if (res != NO_ERROR) {
+        return res;
+    }
+
+    /* Initialize base class. */
+    res = EmulatedCameraDevice::Initialize();
+    if (res == NO_ERROR) {
+        ALOGV("%s: Connected to the emulated camera service '%s'",
+             __FUNCTION__, device_name);
+        mDeviceName = device_name;
+    } else {
+        mQemuClient.queryDisconnect();
+    }
+
+    return res;
+}
+
+/****************************************************************************
+ * Emulated camera device abstract interface implementation.
+ ***************************************************************************/
+
+status_t EmulatedQemuCameraDevice::connectDevice()
+{
+    ALOGV("%s", __FUNCTION__);
+
+    Mutex::Autolock locker(&mObjectLock);
+    if (!isInitialized()) {
+        ALOGE("%s: Qemu camera device is not initialized.", __FUNCTION__);
+        return EINVAL;
+    }
+    if (isConnected()) {
+        ALOGW("%s: Qemu camera device '%s' is already connected.",
+             __FUNCTION__, (const char*)mDeviceName);
+        return NO_ERROR;
+    }
+
+    /* Connect to the camera device via emulator. */
+    const status_t res = mQemuClient.queryConnect();
+    if (res == NO_ERROR) {
+        ALOGV("%s: Connected to device '%s'",
+             __FUNCTION__, (const char*)mDeviceName);
+        mState = ECDS_CONNECTED;
+    } else {
+        ALOGE("%s: Connection to device '%s' failed",
+             __FUNCTION__, (const char*)mDeviceName);
+    }
+
+    return res;
+}
+
+status_t EmulatedQemuCameraDevice::disconnectDevice()
+{
+    ALOGV("%s", __FUNCTION__);
+
+    Mutex::Autolock locker(&mObjectLock);
+    if (!isConnected()) {
+        ALOGW("%s: Qemu camera device '%s' is already disconnected.",
+             __FUNCTION__, (const char*)mDeviceName);
+        return NO_ERROR;
+    }
+    if (isStarted()) {
+        ALOGE("%s: Cannot disconnect from the started device '%s.",
+             __FUNCTION__, (const char*)mDeviceName);
+        return EINVAL;
+    }
+
+    /* Disconnect from the camera device via emulator. */
+    const status_t res = mQemuClient.queryDisconnect();
+    if (res == NO_ERROR) {
+        ALOGV("%s: Disonnected from device '%s'",
+             __FUNCTION__, (const char*)mDeviceName);
+        mState = ECDS_INITIALIZED;
+    } else {
+        ALOGE("%s: Disconnection from device '%s' failed",
+             __FUNCTION__, (const char*)mDeviceName);
+    }
+
+    return res;
+}
+
+status_t EmulatedQemuCameraDevice::startDevice(int width,
+                                               int height,
+                                               uint32_t pix_fmt)
+{
+    ALOGV("%s", __FUNCTION__);
+
+    Mutex::Autolock locker(&mObjectLock);
+    if (!isConnected()) {
+        ALOGE("%s: Qemu camera device '%s' is not connected.",
+             __FUNCTION__, (const char*)mDeviceName);
+        return EINVAL;
+    }
+    if (isStarted()) {
+        ALOGW("%s: Qemu camera device '%s' is already started.",
+             __FUNCTION__, (const char*)mDeviceName);
+        return NO_ERROR;
+    }
+
+    status_t res = EmulatedCameraDevice::commonStartDevice(width, height, pix_fmt);
+    if (res != NO_ERROR) {
+        ALOGE("%s: commonStartDevice failed", __FUNCTION__);
+        return res;
+    }
+
+    /* Allocate preview frame buffer. */
+    /* TODO: Watch out for preview format changes! At this point we implement
+     * RGB32 only.*/
+    mPreviewFrame = new uint32_t[mTotalPixels];
+    if (mPreviewFrame == NULL) {
+        ALOGE("%s: Unable to allocate %d bytes for preview frame",
+             __FUNCTION__, mTotalPixels);
+        return ENOMEM;
+    }
+
+    /* Start the actual camera device. */
+    res = mQemuClient.queryStart(mPixelFormat, mFrameWidth, mFrameHeight);
+    if (res == NO_ERROR) {
+        ALOGV("%s: Qemu camera device '%s' is started for %.4s[%dx%d] frames",
+             __FUNCTION__, (const char*)mDeviceName,
+             reinterpret_cast<const char*>(&mPixelFormat),
+             mFrameWidth, mFrameHeight);
+        mState = ECDS_STARTED;
+    } else {
+        ALOGE("%s: Unable to start device '%s' for %.4s[%dx%d] frames",
+             __FUNCTION__, (const char*)mDeviceName,
+             reinterpret_cast<const char*>(&pix_fmt), width, height);
+    }
+
+    return res;
+}
+
+status_t EmulatedQemuCameraDevice::stopDevice()
+{
+    ALOGV("%s", __FUNCTION__);
+
+    Mutex::Autolock locker(&mObjectLock);
+    if (!isStarted()) {
+        ALOGW("%s: Qemu camera device '%s' is not started.",
+             __FUNCTION__, (const char*)mDeviceName);
+        return NO_ERROR;
+    }
+
+    /* Stop the actual camera device. */
+    status_t res = mQemuClient.queryStop();
+    if (res == NO_ERROR) {
+        if (mPreviewFrame == NULL) {
+            delete[] mPreviewFrame;
+            mPreviewFrame = NULL;
+        }
+        EmulatedCameraDevice::commonStopDevice();
+        mState = ECDS_CONNECTED;
+        ALOGV("%s: Qemu camera device '%s' is stopped",
+             __FUNCTION__, (const char*)mDeviceName);
+    } else {
+        ALOGE("%s: Unable to stop device '%s'",
+             __FUNCTION__, (const char*)mDeviceName);
+    }
+
+    return res;
+}
+
+/****************************************************************************
+ * EmulatedCameraDevice virtual overrides
+ ***************************************************************************/
+
+status_t EmulatedQemuCameraDevice::getCurrentPreviewFrame(void* buffer)
+{
+    ALOGW_IF(mPreviewFrame == NULL, "%s: No preview frame", __FUNCTION__);
+    if (mPreviewFrame != NULL) {
+        memcpy(buffer, mPreviewFrame, mTotalPixels * 4);
+        return 0;
+    } else {
+        return EmulatedCameraDevice::getCurrentPreviewFrame(buffer);
+    }
+}
+
+/****************************************************************************
+ * Worker thread management overrides.
+ ***************************************************************************/
+
+bool EmulatedQemuCameraDevice::inWorkerThread()
+{
+    /* Wait till FPS timeout expires, or thread exit message is received. */
+    WorkerThread::SelectRes res =
+        getWorkerThread()->Select(-1, 1000000 / mEmulatedFPS);
+    if (res == WorkerThread::EXIT_THREAD) {
+        ALOGV("%s: Worker thread has been terminated.", __FUNCTION__);
+        return false;
+    }
+
+    /* Query frames from the service. */
+    status_t query_res = mQemuClient.queryFrame(mCurrentFrame, mPreviewFrame,
+                                                 mFrameBufferSize,
+                                                 mTotalPixels * 4,
+                                                 mWhiteBalanceScale[0],
+                                                 mWhiteBalanceScale[1],
+                                                 mWhiteBalanceScale[2],
+                                                 mExposureCompensation);
+    if (query_res == NO_ERROR) {
+        /* Timestamp the current frame, and notify the camera HAL. */
+        mCurFrameTimestamp = systemTime(SYSTEM_TIME_MONOTONIC);
+        mCameraHAL->onNextFrameAvailable(mCurrentFrame, mCurFrameTimestamp, this);
+        return true;
+    } else {
+        ALOGE("%s: Unable to get current video frame: %s",
+             __FUNCTION__, strerror(query_res));
+        mCameraHAL->onCameraDeviceError(CAMERA_ERROR_SERVER_DIED);
+        return false;
+    }
+}
+
+}; /* namespace android */
diff --git a/camera/EmulatedQemuCameraDevice.h b/camera/EmulatedQemuCameraDevice.h
new file mode 100755
index 0000000..8ef562b
--- /dev/null
+++ b/camera/EmulatedQemuCameraDevice.h
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef HW_EMULATOR_CAMERA_EMULATED_QEMU_CAMERA_DEVICE_H
+#define HW_EMULATOR_CAMERA_EMULATED_QEMU_CAMERA_DEVICE_H
+
+/*
+ * Contains declaration of a class EmulatedQemuCameraDevice that encapsulates
+ * an emulated camera device connected to the host.
+ */
+
+#include "EmulatedCameraDevice.h"
+#include "QemuClient.h"
+
+namespace android {
+
+class EmulatedQemuCamera;
+
+/* Encapsulates an emulated camera device connected to the host.
+ */
+class EmulatedQemuCameraDevice : public EmulatedCameraDevice {
+public:
+    /* Constructs EmulatedQemuCameraDevice instance. */
+    explicit EmulatedQemuCameraDevice(EmulatedQemuCamera* camera_hal);
+
+    /* Destructs EmulatedQemuCameraDevice instance. */
+    ~EmulatedQemuCameraDevice();
+
+    /***************************************************************************
+     * Public API
+     **************************************************************************/
+
+public:
+    /* Initializes EmulatedQemuCameraDevice instance.
+     * Param:
+     *  device_name - Name of the camera device connected to the host. The name
+     *      that is used here must have been reported by the 'factory' camera
+     *      service when it listed camera devices connected to the host.
+     * Return:
+     *  NO_ERROR on success, or an appropriate error status.
+     */
+    status_t Initialize(const char* device_name);
+
+    /***************************************************************************
+     * Emulated camera device abstract interface implementation.
+     * See declarations of these methods in EmulatedCameraDevice class for
+     * information on each of these methods.
+     **************************************************************************/
+
+public:
+    /* Connects to the camera device. */
+    status_t connectDevice();
+
+    /* Disconnects from the camera device. */
+    status_t disconnectDevice();
+
+    /* Starts capturing frames from the camera device. */
+    status_t startDevice(int width, int height, uint32_t pix_fmt);
+
+    /* Stops capturing frames from the camera device. */
+    status_t stopDevice();
+
+    /***************************************************************************
+     * EmulatedCameraDevice virtual overrides
+     * See declarations of these methods in EmulatedCameraDevice class for
+     * information on each of these methods.
+     **************************************************************************/
+
+public:
+    /* Gets current preview fame into provided buffer.
+     * We override this method in order to provide preview frames cached in this
+     * object.
+     */
+    status_t getCurrentPreviewFrame(void* buffer);
+
+    /***************************************************************************
+     * Worker thread management overrides.
+     * See declarations of these methods in EmulatedCameraDevice class for
+     * information on each of these methods.
+     **************************************************************************/
+
+protected:
+    /* Implementation of the worker thread routine. */
+    bool inWorkerThread();
+
+    /***************************************************************************
+     * Qemu camera device data members
+     **************************************************************************/
+
+private:
+    /* Qemu client that is used to communicate with the 'emulated camera'
+     * service, created for this instance in the emulator. */
+    CameraQemuClient    mQemuClient;
+
+    /* Name of the camera device connected to the host. */
+    String8             mDeviceName;
+
+    /* Current preview framebuffer. */
+    uint32_t*           mPreviewFrame;
+
+    /* Emulated FPS (frames per second).
+     * We will emulate 50 FPS. */
+    static const int    mEmulatedFPS = 50;
+};
+
+}; /* namespace android */
+
+#endif  /* HW_EMULATOR_CAMERA_EMULATED_QEMU_CAMERA_DEVICE_H */
diff --git a/camera/JpegCompressor.cpp b/camera/JpegCompressor.cpp
new file mode 100644
index 0000000..8eec52d
--- /dev/null
+++ b/camera/JpegCompressor.cpp
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+/*
+ * Contains implementation of a class NV21JpegCompressor that encapsulates a
+ * converter between NV21, and JPEG formats.
+ */
+
+#define LOG_NDEBUG 0
+#define LOG_TAG "EmulatedCamera_JPEG"
+#include <cutils/log.h>
+#include "JpegCompressor.h"
+
+namespace android {
+
+NV21JpegCompressor::NV21JpegCompressor()
+    : Yuv420SpToJpegEncoder(mStrides)
+{
+}
+
+NV21JpegCompressor::~NV21JpegCompressor()
+{
+}
+
+/****************************************************************************
+ * Public API
+ ***************************************************************************/
+
+status_t NV21JpegCompressor::compressRawImage(const void* image,
+                                              int width,
+                                              int height,
+                                              int quality)
+{
+    ALOGV("%s: %p[%dx%d]", __FUNCTION__, image, width, height);
+    void* pY = const_cast<void*>(image);
+    int offsets[2];
+    offsets[0] = 0;
+    offsets[1] = width * height;
+    mStrides[0] = width;
+    mStrides[1] = width;
+    if (encode(&mStream, pY, width, height, offsets, quality)) {
+        ALOGV("%s: Compressed JPEG: %d[%dx%d] -> %d bytes",
+             __FUNCTION__, (width * height * 12) / 8, width, height, mStream.getOffset());
+        return NO_ERROR;
+    } else {
+        ALOGE("%s: JPEG compression failed", __FUNCTION__);
+        return errno ? errno : EINVAL;
+    }
+}
+
+}; /* namespace android */
diff --git a/camera/JpegCompressor.h b/camera/JpegCompressor.h
new file mode 100644
index 0000000..504ffcd
--- /dev/null
+++ b/camera/JpegCompressor.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef HW_EMULATOR_CAMERA_JPEG_COMPRESSOR_H
+#define HW_EMULATOR_CAMERA_JPEG_COMPRESSOR_H
+
+/*
+ * Contains declaration of a class NV21JpegCompressor that encapsulates a
+ * converter between YV21, and JPEG formats.
+ */
+
+#include <YuvToJpegEncoder.h>
+#include <utils/threads.h>
+
+namespace android {
+
+/* Encapsulates a converter between YV12, and JPEG formats.
+ */
+class NV21JpegCompressor : protected Yuv420SpToJpegEncoder
+{
+public:
+    /* Constructs JpegCompressor instance. */
+    NV21JpegCompressor();
+    /* Destructs JpegCompressor instance. */
+    ~NV21JpegCompressor();
+
+    /****************************************************************************
+     * Public API
+     ***************************************************************************/
+
+public:
+    /* Compresses raw NV21 image into a JPEG.
+     * The compressed image will be saved in mStream member of this class. Use
+     * getCompressedSize method to obtain buffer size of the compressed image,
+     * and getCompressedImage to copy out the compressed image.
+     * Param:
+     *  image - Raw NV21 image.
+     *  width, height - Image dimensions.
+     *  quality - JPEG quality.
+     * Return:
+     *  NO_ERROR on success, or an appropriate error status.
+     *
+     */
+    status_t compressRawImage(const void* image,
+                              int width,
+                              int height,
+                              int quality);
+
+    /* Get size of the compressed JPEG buffer.
+     * This method must be called only after a successful completion of
+     * compressRawImage call.
+     * Return:
+     *  Size of the compressed JPEG buffer.
+     */
+    size_t getCompressedSize() const
+    {
+        return mStream.getOffset();
+    }
+
+    /* Copies out compressed JPEG buffer.
+     * This method must be called only after a successful completion of
+     * compressRawImage call.
+     * Param:
+     *  buff - Buffer where to copy the JPEG. Must be large enough to contain the
+     *      entire image.
+     */
+    void getCompressedImage(void* buff) const
+    {
+        mStream.copyTo(buff);
+    }
+
+    /****************************************************************************
+     * Class data
+     ***************************************************************************/
+
+protected:
+    /* Memory stream where converted JPEG is saved. */
+    SkDynamicMemoryWStream  mStream;
+    /* Strides for Y (the first element), and UV (the second one) panes. */
+    int                     mStrides[2];
+};
+
+}; /* namespace android */
+
+#endif  /* HW_EMULATOR_CAMERA_JPEG_COMPRESSOR_H */
diff --git a/camera/PreviewWindow.cpp b/camera/PreviewWindow.cpp
new file mode 100755
index 0000000..4101ed9
--- /dev/null
+++ b/camera/PreviewWindow.cpp
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+/*
+ * Contains implementation of a class PreviewWindow that encapsulates
+ * functionality of a preview window set via set_preview_window camera HAL API.
+ */
+
+#define LOG_NDEBUG 0
+#define LOG_TAG "EmulatedCamera_Preview"
+#include <cutils/log.h>
+#include <ui/Rect.h>
+#include <ui/GraphicBufferMapper.h>
+#include "EmulatedCameraDevice.h"
+#include "PreviewWindow.h"
+
+namespace android {
+
+PreviewWindow::PreviewWindow()
+    : mPreviewWindow(NULL),
+      mLastPreviewed(0),
+      mPreviewFrameWidth(0),
+      mPreviewFrameHeight(0),
+      mPreviewEnabled(false)
+{
+}
+
+PreviewWindow::~PreviewWindow()
+{
+}
+
+/****************************************************************************
+ * Camera API
+ ***************************************************************************/
+
+status_t PreviewWindow::setPreviewWindow(struct preview_stream_ops* window,
+                                         int preview_fps)
+{
+    ALOGV("%s: current: %p -> new: %p", __FUNCTION__, mPreviewWindow, window);
+
+    status_t res = NO_ERROR;
+    Mutex::Autolock locker(&mObjectLock);
+
+    /* Reset preview info. */
+    mPreviewFrameWidth = mPreviewFrameHeight = 0;
+    mPreviewAfter = 0;
+    mLastPreviewed = 0;
+
+    if (window != NULL) {
+        /* The CPU will write each frame to the preview window buffer.
+         * Note that we delay setting preview window buffer geometry until
+         * frames start to come in. */
+        res = window->set_usage(window, GRALLOC_USAGE_SW_WRITE_OFTEN);
+        if (res == NO_ERROR) {
+            /* Set preview frequency. */
+            mPreviewAfter = 1000000 / preview_fps;
+        } else {
+            window = NULL;
+            res = -res; // set_usage returns a negative errno.
+            ALOGE("%s: Error setting preview window usage %d -> %s",
+                 __FUNCTION__, res, strerror(res));
+        }
+    }
+    mPreviewWindow = window;
+
+    return res;
+}
+
+status_t PreviewWindow::startPreview()
+{
+    ALOGV("%s", __FUNCTION__);
+
+    Mutex::Autolock locker(&mObjectLock);
+    mPreviewEnabled = true;
+
+    return NO_ERROR;
+}
+
+void PreviewWindow::stopPreview()
+{
+    ALOGV("%s", __FUNCTION__);
+
+    Mutex::Autolock locker(&mObjectLock);
+    mPreviewEnabled = false;
+}
+
+/****************************************************************************
+ * Public API
+ ***************************************************************************/
+
+void PreviewWindow::onNextFrameAvailable(const void* frame,
+                                         nsecs_t timestamp,
+                                         EmulatedCameraDevice* camera_dev)
+{
+    int res;
+    Mutex::Autolock locker(&mObjectLock);
+
+    if (!isPreviewEnabled() || mPreviewWindow == NULL || !isPreviewTime()) {
+        return;
+    }
+
+    /* Make sure that preview window dimensions are OK with the camera device */
+    if (adjustPreviewDimensions(camera_dev)) {
+        /* Need to set / adjust buffer geometry for the preview window.
+         * Note that in the emulator preview window uses only RGB for pixel
+         * formats. */
+        ALOGV("%s: Adjusting preview windows %p geometry to %dx%d",
+             __FUNCTION__, mPreviewWindow, mPreviewFrameWidth,
+             mPreviewFrameHeight);
+        res = mPreviewWindow->set_buffers_geometry(mPreviewWindow,
+                                                   mPreviewFrameWidth,
+                                                   mPreviewFrameHeight,
+                                                   HAL_PIXEL_FORMAT_RGBA_8888);
+        if (res != NO_ERROR) {
+            ALOGE("%s: Error in set_buffers_geometry %d -> %s",
+                 __FUNCTION__, -res, strerror(-res));
+            return;
+        }
+    }
+
+    /*
+     * Push new frame to the preview window.
+     */
+
+    /* Dequeue preview window buffer for the frame. */
+    buffer_handle_t* buffer = NULL;
+    int stride = 0;
+    res = mPreviewWindow->dequeue_buffer(mPreviewWindow, &buffer, &stride);
+    if (res != NO_ERROR || buffer == NULL) {
+        ALOGE("%s: Unable to dequeue preview window buffer: %d -> %s",
+            __FUNCTION__, -res, strerror(-res));
+        return;
+    }
+
+    /* Let the preview window to lock the buffer. */
+    res = mPreviewWindow->lock_buffer(mPreviewWindow, buffer);
+    if (res != NO_ERROR) {
+        ALOGE("%s: Unable to lock preview window buffer: %d -> %s",
+             __FUNCTION__, -res, strerror(-res));
+        mPreviewWindow->cancel_buffer(mPreviewWindow, buffer);
+        return;
+    }
+
+    /* Now let the graphics framework to lock the buffer, and provide
+     * us with the framebuffer data address. */
+    void* img = NULL;
+    const Rect rect(mPreviewFrameWidth, mPreviewFrameHeight);
+    GraphicBufferMapper& grbuffer_mapper(GraphicBufferMapper::get());
+    res = grbuffer_mapper.lock(*buffer, GRALLOC_USAGE_SW_WRITE_OFTEN, rect, &img);
+    if (res != NO_ERROR) {
+        ALOGE("%s: grbuffer_mapper.lock failure: %d -> %s",
+             __FUNCTION__, res, strerror(res));
+        mPreviewWindow->cancel_buffer(mPreviewWindow, buffer);
+        return;
+    }
+
+    /* Frames come in in YV12/NV12/NV21 format. Since preview window doesn't
+     * supports those formats, we need to obtain the frame in RGB565. */
+    res = camera_dev->getCurrentPreviewFrame(img);
+    if (res == NO_ERROR) {
+        /* Show it. */
+        mPreviewWindow->set_timestamp(mPreviewWindow, timestamp);
+        mPreviewWindow->enqueue_buffer(mPreviewWindow, buffer);
+    } else {
+        ALOGE("%s: Unable to obtain preview frame: %d", __FUNCTION__, res);
+        mPreviewWindow->cancel_buffer(mPreviewWindow, buffer);
+    }
+    grbuffer_mapper.unlock(*buffer);
+}
+
+/***************************************************************************
+ * Private API
+ **************************************************************************/
+
+bool PreviewWindow::adjustPreviewDimensions(EmulatedCameraDevice* camera_dev)
+{
+    /* Match the cached frame dimensions against the actual ones. */
+    if (mPreviewFrameWidth == camera_dev->getFrameWidth() &&
+        mPreviewFrameHeight == camera_dev->getFrameHeight()) {
+        /* They match. */
+        return false;
+    }
+
+    /* They don't match: adjust the cache. */
+    mPreviewFrameWidth = camera_dev->getFrameWidth();
+    mPreviewFrameHeight = camera_dev->getFrameHeight();
+
+    return true;
+}
+
+bool PreviewWindow::isPreviewTime()
+{
+    timeval cur_time;
+    gettimeofday(&cur_time, NULL);
+    const uint64_t cur_mks = cur_time.tv_sec * 1000000LL + cur_time.tv_usec;
+    if ((cur_mks - mLastPreviewed) >= mPreviewAfter) {
+        mLastPreviewed = cur_mks;
+        return true;
+    }
+    return false;
+}
+
+}; /* namespace android */
diff --git a/camera/PreviewWindow.h b/camera/PreviewWindow.h
new file mode 100755
index 0000000..d037c95
--- /dev/null
+++ b/camera/PreviewWindow.h
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef HW_EMULATOR_CAMERA_PREVIEW_WINDOW_H
+#define HW_EMULATOR_CAMERA_PREVIEW_WINDOW_H
+
+/*
+ * Contains declaration of a class PreviewWindow that encapsulates functionality
+ * of a preview window set via set_preview_window camera HAL API.
+ */
+
+namespace android {
+
+class EmulatedCameraDevice;
+
+/* Encapsulates functionality of a preview window set via set_preview_window
+ * camera HAL API.
+ *
+ * Objects of this class are contained in EmulatedCamera objects, and handle
+ * relevant camera API callbacks.
+ */
+class PreviewWindow {
+public:
+    /* Constructs PreviewWindow instance. */
+    PreviewWindow();
+
+    /* Destructs PreviewWindow instance. */
+    ~PreviewWindow();
+
+    /***************************************************************************
+     * Camera API
+     **************************************************************************/
+
+public:
+    /* Actual handler for camera_device_ops_t::set_preview_window callback.
+     * This method is called by the containing emulated camera object when it is
+     * handing the camera_device_ops_t::set_preview_window callback.
+     * Param:
+     *  window - Preview window to set. This parameter might be NULL, which
+     *      indicates preview window reset.
+     *  preview_fps - Preview's frame frequency. This parameter determins when
+     *      a frame received via onNextFrameAvailable call will be pushed to
+     *      the preview window. If 'window' parameter passed to this method is
+     *      NULL, this parameter is ignored.
+     * Return:
+     *  NO_ERROR on success, or an appropriate error status.
+     */
+    status_t setPreviewWindow(struct preview_stream_ops* window,
+                              int preview_fps);
+
+    /* Starts the preview.
+     * This method is called by the containing emulated camera object when it is
+     * handing the camera_device_ops_t::start_preview callback.
+     */
+    status_t startPreview();
+
+    /* Stops the preview.
+     * This method is called by the containing emulated camera object when it is
+     * handing the camera_device_ops_t::start_preview callback.
+     */
+    void stopPreview();
+
+    /* Checks if preview is enabled. */
+    inline bool isPreviewEnabled()
+    {
+        return mPreviewEnabled;
+    }
+
+    /****************************************************************************
+     * Public API
+     ***************************************************************************/
+
+public:
+    /* Next frame is available in the camera device.
+     * This is a notification callback that is invoked by the camera device when
+     * a new frame is available.
+     * Note that most likely this method is called in context of a worker thread
+     * that camera device has created for frame capturing.
+     * Param:
+     *  frame - Captured frame, or NULL if camera device didn't pull the frame
+     *      yet. If NULL is passed in this parameter use GetCurrentFrame method
+     *      of the camera device class to obtain the next frame. Also note that
+     *      the size of the frame that is passed here (as well as the frame
+     *      returned from the GetCurrentFrame method) is defined by the current
+     *      frame settings (width + height + pixel format) for the camera device.
+     * timestamp - Frame's timestamp.
+     * camera_dev - Camera device instance that delivered the frame.
+     */
+    void onNextFrameAvailable(const void* frame,
+                              nsecs_t timestamp,
+                              EmulatedCameraDevice* camera_dev);
+
+    /***************************************************************************
+     * Private API
+     **************************************************************************/
+
+protected:
+    /* Adjusts cached dimensions of the preview window frame according to the
+     * frame dimensions used by the camera device.
+     *
+     * When preview is started, it's not known (hard to define) what are going
+     * to be the dimensions of the frames that are going to be displayed. Plus,
+     * it might be possible, that such dimensions can be changed on the fly. So,
+     * in order to be always in sync with frame dimensions, this method is
+     * called for each frame passed to onNextFrameAvailable method, in order to
+     * properly adjust frame dimensions, used by the preview window.
+     * Note that this method must be called while object is locked.
+     * Param:
+     *  camera_dev - Camera device, prpviding frames displayed in the preview
+     *      window.
+     * Return:
+     *  true if cached dimensions have been adjusted, or false if cached
+     *  dimensions match device's frame dimensions.
+     */
+    bool adjustPreviewDimensions(EmulatedCameraDevice* camera_dev);
+
+    /* Checks if it's the time to push new frame to the preview window.
+     * Note that this method must be called while object is locked. */
+    bool isPreviewTime();
+
+    /***************************************************************************
+     * Data members
+     **************************************************************************/
+
+protected:
+    /* Locks this instance for data changes. */
+    Mutex                           mObjectLock;
+
+    /* Preview window instance. */
+    preview_stream_ops*             mPreviewWindow;
+
+    /* Timestamp (abs. microseconds) when last frame has been pushed to the
+     * preview window. */
+    uint64_t                        mLastPreviewed;
+
+    /* Preview frequency in microseconds. */
+    uint32_t                        mPreviewAfter;
+
+    /*
+     * Cached preview window frame dimensions.
+     */
+
+    int                             mPreviewFrameWidth;
+    int                             mPreviewFrameHeight;
+
+    /* Preview status. */
+    bool                            mPreviewEnabled;
+};
+
+}; /* namespace android */
+
+#endif  /* HW_EMULATOR_CAMERA_PREVIEW_WINDOW_H */
diff --git a/camera/QemuClient.cpp b/camera/QemuClient.cpp
new file mode 100755
index 0000000..17e6f98
--- /dev/null
+++ b/camera/QemuClient.cpp
@@ -0,0 +1,559 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+/*
+ * Contains implementation of classes that encapsulate connection to camera
+ * services in the emulator via qemu pipe.
+ */
+
+#define LOG_NDEBUG 1
+#define LOG_TAG "EmulatedCamera_QemuClient"
+#include <cutils/log.h>
+#include "EmulatedCamera.h"
+#include "QemuClient.h"
+
+#define LOG_QUERIES 0
+#if LOG_QUERIES
+#define LOGQ(...)   ALOGD(__VA_ARGS__)
+#else
+#define LOGQ(...)   (void(0))
+
+#endif  // LOG_QUERIES
+namespace android {
+
+/****************************************************************************
+ * Qemu query
+ ***************************************************************************/
+
+QemuQuery::QemuQuery()
+    : mQuery(mQueryPrealloc),
+      mQueryDeliveryStatus(NO_ERROR),
+      mReplyBuffer(NULL),
+      mReplyData(NULL),
+      mReplySize(0),
+      mReplyDataSize(0),
+      mReplyStatus(0)
+{
+    *mQuery = '\0';
+}
+
+QemuQuery::QemuQuery(const char* query_string)
+    : mQuery(mQueryPrealloc),
+      mQueryDeliveryStatus(NO_ERROR),
+      mReplyBuffer(NULL),
+      mReplyData(NULL),
+      mReplySize(0),
+      mReplyDataSize(0),
+      mReplyStatus(0)
+{
+    mQueryDeliveryStatus = QemuQuery::createQuery(query_string, NULL);
+}
+
+QemuQuery::QemuQuery(const char* query_name, const char* query_param)
+    : mQuery(mQueryPrealloc),
+      mQueryDeliveryStatus(NO_ERROR),
+      mReplyBuffer(NULL),
+      mReplyData(NULL),
+      mReplySize(0),
+      mReplyDataSize(0),
+      mReplyStatus(0)
+{
+    mQueryDeliveryStatus = QemuQuery::createQuery(query_name, query_param);
+}
+
+QemuQuery::~QemuQuery()
+{
+    QemuQuery::resetQuery();
+}
+
+status_t QemuQuery::createQuery(const char* name, const char* param)
+{
+    /* Reset from the previous use. */
+    resetQuery();
+
+    /* Query name cannot be NULL or an empty string. */
+    if (name == NULL || *name == '\0') {
+        ALOGE("%s: NULL or an empty string is passed as query name.",
+             __FUNCTION__);
+        mQueryDeliveryStatus = EINVAL;
+        return EINVAL;
+    }
+
+    const size_t name_len = strlen(name);
+    const size_t param_len = (param != NULL) ? strlen(param) : 0;
+    const size_t required = strlen(name) + (param_len ? (param_len + 2) : 1);
+
+    if (required > sizeof(mQueryPrealloc)) {
+        /* Preallocated buffer was too small. Allocate a bigger query buffer. */
+        mQuery = new char[required];
+        if (mQuery == NULL) {
+            ALOGE("%s: Unable to allocate %d bytes for query buffer",
+                 __FUNCTION__, required);
+            mQueryDeliveryStatus = ENOMEM;
+            return ENOMEM;
+        }
+    }
+
+    /* At this point mQuery buffer is big enough for the query. */
+    if (param_len) {
+        sprintf(mQuery, "%s %s", name, param);
+    } else {
+        memcpy(mQuery, name, name_len + 1);
+    }
+
+    return NO_ERROR;
+}
+
+status_t QemuQuery::completeQuery(status_t status)
+{
+    /* Save query completion status. */
+    mQueryDeliveryStatus = status;
+    if (mQueryDeliveryStatus != NO_ERROR) {
+        return mQueryDeliveryStatus;
+    }
+
+    /* Make sure reply buffer contains at least 'ok', or 'ko'.
+     * Note that 'ok', or 'ko' prefixes are always 3 characters long: in case
+     * there are more data in the reply, that data will be separated from 'ok'/'ko'
+     * with a ':'. If there is no more data in the reply, the prefix will be
+     * zero-terminated, and the terminator will be inculded in the reply. */
+    if (mReplyBuffer == NULL || mReplySize < 3) {
+        ALOGE("%s: Invalid reply to the query", __FUNCTION__);
+        mQueryDeliveryStatus = EINVAL;
+        return EINVAL;
+    }
+
+    /* Lets see the reply status. */
+    if (!memcmp(mReplyBuffer, "ok", 2)) {
+        mReplyStatus = 1;
+    } else if (!memcmp(mReplyBuffer, "ko", 2)) {
+        mReplyStatus = 0;
+    } else {
+        ALOGE("%s: Invalid query reply: '%s'", __FUNCTION__, mReplyBuffer);
+        mQueryDeliveryStatus = EINVAL;
+        return EINVAL;
+    }
+
+    /* Lets see if there are reply data that follow. */
+    if (mReplySize > 3) {
+        /* There are extra data. Make sure they are separated from the status
+         * with a ':' */
+        if (mReplyBuffer[2] != ':') {
+            ALOGE("%s: Invalid query reply: '%s'", __FUNCTION__, mReplyBuffer);
+            mQueryDeliveryStatus = EINVAL;
+            return EINVAL;
+        }
+        mReplyData = mReplyBuffer + 3;
+        mReplyDataSize = mReplySize - 3;
+    } else {
+        /* Make sure reply buffer containing just 'ok'/'ko' ends with
+         * zero-terminator. */
+        if (mReplyBuffer[2] != '\0') {
+            ALOGE("%s: Invalid query reply: '%s'", __FUNCTION__, mReplyBuffer);
+            mQueryDeliveryStatus = EINVAL;
+            return EINVAL;
+        }
+    }
+
+    return NO_ERROR;
+}
+
+void QemuQuery::resetQuery()
+{
+    if (mQuery != NULL && mQuery != mQueryPrealloc) {
+        delete[] mQuery;
+    }
+    mQuery = mQueryPrealloc;
+    mQueryDeliveryStatus = NO_ERROR;
+    if (mReplyBuffer != NULL) {
+        free(mReplyBuffer);
+        mReplyBuffer = NULL;
+    }
+    mReplyData = NULL;
+    mReplySize = mReplyDataSize = 0;
+    mReplyStatus = 0;
+}
+
+/****************************************************************************
+ * Qemu client base
+ ***************************************************************************/
+
+/* Camera service name. */
+const char QemuClient::mCameraServiceName[]   = "camera";
+
+QemuClient::QemuClient()
+    : mPipeFD(-1)
+{
+}
+
+QemuClient::~QemuClient()
+{
+    if (mPipeFD >= 0) {
+        close(mPipeFD);
+    }
+}
+
+/****************************************************************************
+ * Qemu client API
+ ***************************************************************************/
+
+status_t QemuClient::connectClient(const char* param)
+{
+    ALOGV("%s: '%s'", __FUNCTION__, param ? param : "");
+
+    /* Make sure that client is not connected already. */
+    if (mPipeFD >= 0) {
+        ALOGE("%s: Qemu client is already connected", __FUNCTION__);
+        return EINVAL;
+    }
+
+    /* Select one of the two: 'factory', or 'emulated camera' service */
+    if (param == NULL || *param == '\0') {
+        /* No parameters: connect to the factory service. */
+        char pipe_name[512];
+        snprintf(pipe_name, sizeof(pipe_name), "qemud:%s", mCameraServiceName);
+        mPipeFD = qemu_pipe_open(pipe_name);
+    } else {
+        /* One extra char ':' that separates service name and parameters + six
+         * characters for 'qemud:'. This is required by qemu pipe protocol. */
+        char* connection_str = new char[strlen(mCameraServiceName) +
+                                        strlen(param) + 8];
+        sprintf(connection_str, "qemud:%s:%s", mCameraServiceName, param);
+
+        mPipeFD = qemu_pipe_open(connection_str);
+        delete[] connection_str;
+    }
+    if (mPipeFD < 0) {
+        ALOGE("%s: Unable to connect to the camera service '%s': %s",
+             __FUNCTION__, param ? param : "Factory", strerror(errno));
+        return errno ? errno : EINVAL;
+    }
+
+    return NO_ERROR;
+}
+
+void QemuClient::disconnectClient()
+{
+    ALOGV("%s", __FUNCTION__);
+
+    if (mPipeFD >= 0) {
+        close(mPipeFD);
+        mPipeFD = -1;
+    }
+}
+
+status_t QemuClient::sendMessage(const void* data, size_t data_size)
+{
+    if (mPipeFD < 0) {
+        ALOGE("%s: Qemu client is not connected", __FUNCTION__);
+        return EINVAL;
+    }
+
+    /* Note that we don't use here qemud_client_send, since with qemu pipes we
+     * don't need to provide payload size prior to payload when we're writing to
+     * the pipe. So, we can use simple write, and qemu pipe will take care of the
+     * rest, calling the receiving end with the number of bytes transferred. */
+    const size_t written = qemud_fd_write(mPipeFD, data, data_size);
+    if (written == data_size) {
+        return NO_ERROR;
+    } else {
+        ALOGE("%s: Error sending data via qemu pipe: '%s'",
+             __FUNCTION__, strerror(errno));
+        return errno ? errno : EIO;
+    }
+}
+
+status_t QemuClient::receiveMessage(void** data, size_t* data_size)
+{
+    *data = NULL;
+    *data_size = 0;
+
+    if (mPipeFD < 0) {
+        ALOGE("%s: Qemu client is not connected", __FUNCTION__);
+        return EINVAL;
+    }
+
+    /* The way the service replies to a query, it sends payload size first, and
+     * then it sends the payload itself. Note that payload size is sent as a
+     * string, containing 8 characters representing a hexadecimal payload size
+     * value. Note also, that the string doesn't contain zero-terminator. */
+    size_t payload_size;
+    char payload_size_str[9];
+    int rd_res = qemud_fd_read(mPipeFD, payload_size_str, 8);
+    if (rd_res != 8) {
+        ALOGE("%s: Unable to obtain payload size: %s",
+             __FUNCTION__, strerror(errno));
+        return errno ? errno : EIO;
+    }
+
+    /* Convert payload size. */
+    errno = 0;
+    payload_size_str[8] = '\0';
+    payload_size = strtol(payload_size_str, NULL, 16);
+    if (errno) {
+        ALOGE("%s: Invalid payload size '%s'", __FUNCTION__, payload_size_str);
+        return EIO;
+    }
+
+    /* Allocate payload data buffer, and read the payload there. */
+    *data = malloc(payload_size);
+    if (*data == NULL) {
+        ALOGE("%s: Unable to allocate %d bytes payload buffer",
+             __FUNCTION__, payload_size);
+        return ENOMEM;
+    }
+    rd_res = qemud_fd_read(mPipeFD, *data, payload_size);
+    if (static_cast<size_t>(rd_res) == payload_size) {
+        *data_size = payload_size;
+        return NO_ERROR;
+    } else {
+        ALOGE("%s: Read size %d doesnt match expected payload size %d: %s",
+             __FUNCTION__, rd_res, payload_size, strerror(errno));
+        free(*data);
+        *data = NULL;
+        return errno ? errno : EIO;
+    }
+}
+
+status_t QemuClient::doQuery(QemuQuery* query)
+{
+    /* Make sure that query has been successfuly constructed. */
+    if (query->mQueryDeliveryStatus != NO_ERROR) {
+        ALOGE("%s: Query is invalid", __FUNCTION__);
+        return query->mQueryDeliveryStatus;
+    }
+
+    LOGQ("Send query '%s'", query->mQuery);
+
+    /* Send the query. */
+    status_t res = sendMessage(query->mQuery, strlen(query->mQuery) + 1);
+    if (res == NO_ERROR) {
+        /* Read the response. */
+        res = receiveMessage(reinterpret_cast<void**>(&query->mReplyBuffer),
+                      &query->mReplySize);
+        if (res == NO_ERROR) {
+            LOGQ("Response to query '%s': Status = '%.2s', %d bytes in response",
+                 query->mQuery, query->mReplyBuffer, query->mReplySize);
+        } else {
+            ALOGE("%s Response to query '%s' has failed: %s",
+                 __FUNCTION__, query->mQuery, strerror(res));
+        }
+    } else {
+        ALOGE("%s: Send query '%s' failed: %s",
+             __FUNCTION__, query->mQuery, strerror(res));
+    }
+
+    /* Complete the query, and return its completion handling status. */
+    const status_t res1 = query->completeQuery(res);
+    ALOGE_IF(res1 != NO_ERROR && res1 != res,
+            "%s: Error %d in query '%s' completion",
+            __FUNCTION__, res1, query->mQuery);
+    return res1;
+}
+
+/****************************************************************************
+ * Qemu client for the 'factory' service.
+ ***************************************************************************/
+
+/*
+ * Factory service queries.
+ */
+
+/* Queries list of cameras connected to the host. */
+const char FactoryQemuClient::mQueryList[] = "list";
+
+FactoryQemuClient::FactoryQemuClient()
+    : QemuClient()
+{
+}
+
+FactoryQemuClient::~FactoryQemuClient()
+{
+}
+
+status_t FactoryQemuClient::listCameras(char** list)
+{
+    ALOGV("%s", __FUNCTION__);
+
+    QemuQuery query(mQueryList);
+    if (doQuery(&query) || !query.isQuerySucceeded()) {
+        ALOGE("%s: List cameras query failed: %s", __FUNCTION__,
+             query.mReplyData ? query.mReplyData : "No error message");
+        return query.getCompletionStatus();
+    }
+
+    /* Make sure there is a list returned. */
+    if (query.mReplyDataSize == 0) {
+        ALOGE("%s: No camera list is returned.", __FUNCTION__);
+        return EINVAL;
+    }
+
+    /* Copy the list over. */
+    *list = (char*)malloc(query.mReplyDataSize);
+    if (*list != NULL) {
+        memcpy(*list, query.mReplyData, query.mReplyDataSize);
+        ALOGD("Emulated camera list: %s", *list);
+        return NO_ERROR;
+    } else {
+        ALOGE("%s: Unable to allocate %d bytes",
+             __FUNCTION__, query.mReplyDataSize);
+        return ENOMEM;
+    }
+}
+
+/****************************************************************************
+ * Qemu client for an 'emulated camera' service.
+ ***************************************************************************/
+
+/*
+ * Emulated camera queries
+ */
+
+/* Connect to the camera device. */
+const char CameraQemuClient::mQueryConnect[]    = "connect";
+/* Disconect from the camera device. */
+const char CameraQemuClient::mQueryDisconnect[] = "disconnect";
+/* Start capturing video from the camera device. */
+const char CameraQemuClient::mQueryStart[]      = "start";
+/* Stop capturing video from the camera device. */
+const char CameraQemuClient::mQueryStop[]       = "stop";
+/* Get next video frame from the camera device. */
+const char CameraQemuClient::mQueryFrame[]      = "frame";
+
+CameraQemuClient::CameraQemuClient()
+    : QemuClient()
+{
+}
+
+CameraQemuClient::~CameraQemuClient()
+{
+
+}
+
+status_t CameraQemuClient::queryConnect()
+{
+    ALOGV("%s", __FUNCTION__);
+
+    QemuQuery query(mQueryConnect);
+    doQuery(&query);
+    const status_t res = query.getCompletionStatus();
+    ALOGE_IF(res != NO_ERROR, "%s: Query failed: %s",
+            __FUNCTION__, query.mReplyData ? query.mReplyData :
+                                             "No error message");
+    return res;
+}
+
+status_t CameraQemuClient::queryDisconnect()
+{
+    ALOGV("%s", __FUNCTION__);
+
+    QemuQuery query(mQueryDisconnect);
+    doQuery(&query);
+    const status_t res = query.getCompletionStatus();
+    ALOGE_IF(res != NO_ERROR, "%s: Query failed: %s",
+            __FUNCTION__, query.mReplyData ? query.mReplyData :
+                                             "No error message");
+    return res;
+}
+
+status_t CameraQemuClient::queryStart(uint32_t pixel_format,
+                                      int width,
+                                      int height)
+{
+    ALOGV("%s", __FUNCTION__);
+
+    char query_str[256];
+    snprintf(query_str, sizeof(query_str), "%s dim=%dx%d pix=%d",
+             mQueryStart, width, height, pixel_format);
+    QemuQuery query(query_str);
+    doQuery(&query);
+    const status_t res = query.getCompletionStatus();
+    ALOGE_IF(res != NO_ERROR, "%s: Query failed: %s",
+            __FUNCTION__, query.mReplyData ? query.mReplyData :
+                                             "No error message");
+    return res;
+}
+
+status_t CameraQemuClient::queryStop()
+{
+    ALOGV("%s", __FUNCTION__);
+
+    QemuQuery query(mQueryStop);
+    doQuery(&query);
+    const status_t res = query.getCompletionStatus();
+    ALOGE_IF(res != NO_ERROR, "%s: Query failed: %s",
+            __FUNCTION__, query.mReplyData ? query.mReplyData :
+                                             "No error message");
+    return res;
+}
+
+status_t CameraQemuClient::queryFrame(void* vframe,
+                                      void* pframe,
+                                      size_t vframe_size,
+                                      size_t pframe_size,
+                                      float r_scale,
+                                      float g_scale,
+                                      float b_scale,
+                                      float exposure_comp)
+{
+    ALOGV("%s", __FUNCTION__);
+
+    char query_str[256];
+    snprintf(query_str, sizeof(query_str), "%s video=%d preview=%d whiteb=%g,%g,%g expcomp=%g",
+             mQueryFrame, (vframe && vframe_size) ? vframe_size : 0,
+             (pframe && pframe_size) ? pframe_size : 0, r_scale, g_scale, b_scale,
+             exposure_comp);
+    QemuQuery query(query_str);
+    doQuery(&query);
+    const status_t res = query.getCompletionStatus();
+    if( res != NO_ERROR) {
+        ALOGE("%s: Query failed: %s",
+             __FUNCTION__, query.mReplyData ? query.mReplyData :
+                                              "No error message");
+        return res;
+    }
+
+    /* Copy requested frames. */
+    size_t cur_offset = 0;
+    const uint8_t* frame = reinterpret_cast<const uint8_t*>(query.mReplyData);
+    /* Video frame is always first. */
+    if (vframe != NULL && vframe_size != 0) {
+        /* Make sure that video frame is in. */
+        if ((query.mReplyDataSize - cur_offset) >= vframe_size) {
+            memcpy(vframe, frame, vframe_size);
+            cur_offset += vframe_size;
+        } else {
+            ALOGE("%s: Reply %d bytes is to small to contain %d bytes video frame",
+                 __FUNCTION__, query.mReplyDataSize - cur_offset, vframe_size);
+            return EINVAL;
+        }
+    }
+    if (pframe != NULL && pframe_size != 0) {
+        /* Make sure that preview frame is in. */
+        if ((query.mReplyDataSize - cur_offset) >= pframe_size) {
+            memcpy(pframe, frame + cur_offset, pframe_size);
+            cur_offset += pframe_size;
+        } else {
+            ALOGE("%s: Reply %d bytes is to small to contain %d bytes preview frame",
+                 __FUNCTION__, query.mReplyDataSize - cur_offset, pframe_size);
+            return EINVAL;
+        }
+    }
+
+    return NO_ERROR;
+}
+
+}; /* namespace android */
diff --git a/camera/QemuClient.h b/camera/QemuClient.h
new file mode 100755
index 0000000..1644321
--- /dev/null
+++ b/camera/QemuClient.h
@@ -0,0 +1,437 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef HW_EMULATOR_CAMERA_QEMU_CLIENT_H
+#define HW_EMULATOR_CAMERA_QEMU_CLIENT_H
+
+/*
+ * Contains declaration of classes that encapsulate connection to camera services
+ * in the emulator via qemu pipe.
+ */
+
+#include <hardware/qemud.h>
+
+namespace android {
+
+/****************************************************************************
+ * Qemu query
+ ***************************************************************************/
+
+/* Encapsulates a query to the emulator.
+ * Guest exchanges data with the emulator via queries sent over the qemu pipe.
+ * The queries as well as replies to the queries are all strings (except for the
+ * 'frame' query where reply is a framebuffer).
+ * Each query is formatted as such:
+ *
+ *      "<query name>[ <parameters>]",
+ *
+ * where <query name> is a string representing query name, and <parameters> are
+ * optional parameters for the query. If parameters are present, they must be
+ * separated from the query name with a single space, and they must be formatted
+ * as such:
+ *
+ *      "<name1>=<value1> <name2>=<value2> ... <nameN>=<valueN>"
+ *
+ * I.e.:
+ *  - Every parameter must have a name, and a value.
+ *  - Name and value must be separated with '='.
+ *  - No spaces are allowed around '=' separating name and value.
+ *  - Parameters must be separated with a single space character.
+ *  - No '=' character is allowed in name and in value.
+ *
+ * There are certain restrictions on strings used in the query:
+ *  - Spaces are allowed only as separators.
+ *  - '=' are allowed only to divide parameter names from parameter values.
+ *
+ * Emulator replies to each query in two chunks:
+ * - 8 bytes encoding the payload size as a string containing hexadecimal
+ *   representation of the payload size value. This is done in order to simplify
+ *   dealing with different endianness on the host, and on the guest.
+ * - Payload, whose size is defined by the first chunk.
+ *
+ * Every payload always begins with two characters, encoding the result of the
+ * query:
+ *  - 'ok' Encoding the success
+ *  - 'ko' Encoding a failure.
+ * After that payload may have optional data. If payload has more data following
+ * the query result, there is a ':' character separating them. If payload carries
+ * only the result, it always ends with a zero-terminator. So, payload 'ok'/'ko'
+ * prefix is always 3 bytes long: it either includes a zero-terminator, if there
+ * is no data, or a ':' separator.
+ */
+class QemuQuery {
+public:
+    /* Constructs an uninitialized QemuQuery instance. */
+    QemuQuery();
+
+    /* Constructs and initializes QemuQuery instance for a query.
+     * Param:
+     *  query_string - Query string. This constructor can also be used to
+     *      construct a query that doesn't have parameters. In this case query
+     *      name can be passed as a parameter here.
+     */
+    explicit QemuQuery(const char* query_string);
+
+    /* Constructs and initializes QemuQuery instance for a query with parameters.
+     * Param:
+     *  query_name - Query name.
+     *  query_param - Query parameters. Can be NULL.
+     */
+    QemuQuery(const char* query_name, const char* query_param);
+
+    /* Destructs QemuQuery instance. */
+    ~QemuQuery();
+
+    /****************************************************************************
+     * Public API
+     ***************************************************************************/
+
+    /* Creates new query.
+     * Note: this method will reset this instance prior to creating a new query
+     * in order to discard possible "leftovers" from the previous query.
+     * Param:
+     *  query_name - Query name.
+     *  query_param - Query parameters. Can be NULL.
+     * Return:
+     *  NO_ERROR on success, or an appropriate error status.
+     */
+    status_t createQuery(const char* name, const char* param);
+
+    /* Completes the query after a reply from the emulator.
+     * This method will parse the reply buffer, and calculate the final query
+     * status, which depends not only on the transport success / failure, but
+     * also on 'ok' / 'ko' in the reply buffer.
+     * Param:
+     *  status - Query delivery status. This status doesn't necessarily reflects
+     *      the final query status (which is defined by 'ok'/'ko' prefix in the
+     *      reply buffer). This status simply states whether or not the query has
+     *      been sent, and a reply has been received successfuly. However, if
+     *      this status indicates a failure, it means that the entire query has
+     *      failed.
+     * Return:
+     *  NO_ERROR on success, or an appropriate error status on failure. Note that
+     *  status returned here just signals whether or not the method has succeeded.
+     *  Use isQuerySucceeded() / getCompletionStatus() methods of this class to
+     *  check the final query status.
+     */
+    status_t completeQuery(status_t status);
+
+    /* Resets the query from a previous use. */
+    void resetQuery();
+
+    /* Checks if query has succeeded.
+     * Note that this method must be called after completeQuery() method of this
+     * class has been executed.
+     */
+    inline bool isQuerySucceeded() const {
+        return mQueryDeliveryStatus == NO_ERROR && mReplyStatus != 0;
+    }
+
+    /* Gets final completion status of the query.
+     * Note that this method must be called after completeQuery() method of this
+     * class has been executed.
+     * Return:
+     *  NO_ERROR if query has succeeded, or an appropriate error status on query
+     *  failure.
+     */
+    inline status_t getCompletionStatus() const {
+        if (mQueryDeliveryStatus == NO_ERROR) {
+            if (mReplyStatus) {
+                return NO_ERROR;
+            } else {
+                return EINVAL;
+            }
+        } else {
+            return mQueryDeliveryStatus;
+        }
+    }
+
+    /****************************************************************************
+     * Public data memebers
+     ***************************************************************************/
+
+public:
+    /* Query string. */
+    char*       mQuery;
+    /* Query delivery status. */
+    status_t    mQueryDeliveryStatus;
+    /* Reply buffer */
+    char*       mReplyBuffer;
+    /* Reply data (past 'ok'/'ko'). If NULL, there were no data in reply. */
+    char*       mReplyData;
+    /* Reply buffer size. */
+    size_t      mReplySize;
+    /* Reply data size. */
+    size_t      mReplyDataSize;
+    /* Reply status: 1 - ok, 0 - ko. */
+    int         mReplyStatus;
+
+    /****************************************************************************
+     * Private data memebers
+     ***************************************************************************/
+
+protected:
+    /* Preallocated buffer for small queries. */
+    char    mQueryPrealloc[256];
+};
+
+/****************************************************************************
+ * Qemu client base
+ ***************************************************************************/
+
+/* Encapsulates a connection to the 'camera' service in the emulator via qemu
+ * pipe.
+ */
+class QemuClient {
+public:
+    /* Constructs QemuClient instance. */
+    QemuClient();
+
+    /* Destructs QemuClient instance. */
+    virtual ~QemuClient();
+
+    /****************************************************************************
+     * Qemu client API
+     ***************************************************************************/
+
+public:
+    /* Connects to the 'camera' service in the emulator via qemu pipe.
+     * Param:
+     *  param - Parameters to pass to the camera service. There are two types of
+     *      camera services implemented by the emulator. The first one is a
+     *      'camera factory' type of service that provides list of cameras
+     *      connected to the host. Another one is an 'emulated camera' type of
+     *      service that provides interface to a camera connected to the host. At
+     *      the connection time emulator makes distinction between the two by
+     *      looking at connection parameters: no parameters means connection to
+     *      the 'factory' service, while connection with parameters means
+     *      connection to an 'emulated camera' service, where camera is identified
+     *      by one of the connection parameters. So, passing NULL, or an empty
+     *      string to this method will establish a connection with the 'factory'
+     *      service, while not empty string passed here will establish connection
+     *      with an 'emulated camera' service. Parameters defining the emulated
+     *      camera must be formatted as such:
+     *
+     *          "name=<device name> [inp_channel=<input channel #>]",
+     *
+     *      where 'device name' is a required parameter defining name of the
+     *      camera device, and 'input channel' is an optional parameter (positive
+     *      integer), defining the input channel to use on the camera device.
+     *      Note that device name passed here must have been previously obtained
+     *      from the factory service using 'list' query.
+     * Return:
+     *  NO_ERROR on success, or an appropriate error status.
+     */
+    virtual status_t connectClient(const char* param);
+
+    /* Disconnects from the service. */
+    virtual void disconnectClient();
+
+    /* Sends data to the service.
+     * Param:
+     *  data, data_size - Data to send.
+     * Return:
+     *  NO_ERROR on success, or an appropriate error status on failure.
+     */
+    virtual status_t sendMessage(const void* data, size_t data_size);
+
+    /* Receives data from the service.
+     * This method assumes that data to receive will come in two chunks: 8
+     * characters encoding the payload size in hexadecimal string, followed by
+     * the paylod (if any).
+     * This method will allocate data buffer where to receive the response.
+     * Param:
+     *  data - Upon success contains address of the allocated data buffer with
+     *      the data received from the service. The caller is responsible for
+     *      freeing allocated data buffer.
+     *  data_size - Upon success contains size of the data received from the
+     *      service.
+     * Return:
+     *  NO_ERROR on success, or an appropriate error status on failure.
+     */
+    virtual status_t receiveMessage(void** data, size_t* data_size);
+
+    /* Sends a query, and receives a response from the service.
+     * Param:
+     *  query - Query to send to the service. When this method returns, the query
+     *  is completed, and all its relevant data members are properly initialized.
+     * Return:
+     *  NO_ERROR on success, or an appropriate error status on failure. Note that
+     *  status returned here is not the final query status. Use isQuerySucceeded(),
+     *  or getCompletionStatus() method on the query object to see if it has
+     *  succeeded. However, if this method returns a failure, it means that the
+     *  query has failed, and there is no guarantee that its data members are
+     *  properly initialized (except for the 'mQueryDeliveryStatus', which is
+     *  always in the proper state).
+     */
+    virtual status_t doQuery(QemuQuery* query);
+
+    /****************************************************************************
+     * Data members
+     ***************************************************************************/
+
+protected:
+    /* Qemu pipe handle. */
+    int     mPipeFD;
+
+private:
+    /* Camera service name. */
+    static const char mCameraServiceName[];
+};
+
+/****************************************************************************
+ * Qemu client for the 'factory' service.
+ ***************************************************************************/
+
+/* Encapsulates QemuClient for the 'factory' service. */
+class FactoryQemuClient : public QemuClient {
+public:
+    /* Constructs FactoryQemuClient instance. */
+    FactoryQemuClient();
+
+    /* Destructs FactoryQemuClient instance. */
+    ~FactoryQemuClient();
+
+    /****************************************************************************
+     * Public API
+     ***************************************************************************/
+
+public:
+    /* Lists camera devices connected to the host.
+     * Param:
+     *  list - Upon success contains a list of cameras connected to the host. The
+     *      list returned here is represented as a string, containing multiple
+     *      lines separated with '\n', where each line represents a camera. Each
+     *      camera line is formatted as such:
+     *
+     *          "name=<device name> channel=<num> pix=<num> framedims=<dimensions>\n"
+     *
+     *      Where:
+     *      - 'name' is the name of the camera device attached to the host. This
+     *        name must be used for subsequent connection to the 'emulated camera'
+     *        service for that camera.
+     *      - 'channel' - input channel number (positive int) to use to communicate
+     *        with the camera.
+     *      - 'pix' - pixel format (a "fourcc" uint), chosen for the video frames
+     *        by the camera service.
+     *      - 'framedims' contains a list of frame dimensions supported by the
+     *        camera for the chosen pixel format. Each etry in the list is in form
+     *        '<width>x<height>', where 'width' and 'height' are numeric values
+     *        for width and height of a supported frame dimension. Entries in
+     *        this list are separated with ',' with no spaces between the entries.
+     * Return:
+     *  NO_ERROR on success, or an appropriate error status on failure.
+     */
+    status_t listCameras(char** list);
+
+    /****************************************************************************
+     * Names of the queries available for the emulated camera factory.
+     ***************************************************************************/
+
+private:
+    /* List cameras connected to the host. */
+    static const char mQueryList[];
+};
+
+/****************************************************************************
+ * Qemu client for an 'emulated camera' service.
+ ***************************************************************************/
+
+/* Encapsulates QemuClient for an 'emulated camera' service.
+ */
+class CameraQemuClient : public QemuClient {
+public:
+    /* Constructs CameraQemuClient instance. */
+    CameraQemuClient();
+
+    /* Destructs CameraQemuClient instance. */
+    ~CameraQemuClient();
+
+    /****************************************************************************
+     * Public API
+     ***************************************************************************/
+
+public:
+    /* Queries camera connection.
+     * Return:
+     *  NO_ERROR on success, or an appropriate error status on failure.
+     */
+    status_t queryConnect();
+
+    /* Queries camera disconnection.
+     * Return:
+     *  NO_ERROR on success, or an appropriate error status on failure.
+     */
+    status_t queryDisconnect();
+
+    /* Queries camera to start capturing video.
+     * Param:
+     *  pixel_format - Pixel format that is used by the client to push video
+     *      frames to the camera framework.
+     *  width, height - Frame dimensions, requested by the framework.
+     * Return:
+     *  NO_ERROR on success, or an appropriate error status on failure.
+     */
+    status_t queryStart(uint32_t pixel_format, int width, int height);
+
+    /* Queries camera to stop capturing video.
+     * Return:
+     *  NO_ERROR on success, or an appropriate error status on failure.
+     */
+    status_t queryStop();
+
+    /* Queries camera for the next video frame.
+     * Param:
+     *  vframe, vframe_size - Define buffer, allocated to receive a video frame.
+     *      Any of these parameters can be 0, indicating that the caller is
+     *      interested only in preview frame.
+     *  pframe, pframe_size - Define buffer, allocated to receive a preview frame.
+     *      Any of these parameters can be 0, indicating that the caller is
+     *      interested only in video frame.
+     *  r_scale, g_scale, b_scale - White balance scale.
+     *  exposure_comp - Expsoure compensation.
+     * Return:
+     *  NO_ERROR on success, or an appropriate error status on failure.
+     */
+    status_t queryFrame(void* vframe,
+                        void* pframe,
+                        size_t vframe_size,
+                        size_t pframe_size,
+                        float r_scale,
+                        float g_scale,
+                        float b_scale,
+                        float exposure_comp);
+
+    /****************************************************************************
+     * Names of the queries available for the emulated camera.
+     ***************************************************************************/
+
+private:
+    /* Connect to the camera. */
+    static const char mQueryConnect[];
+    /* Disconnect from the camera. */
+    static const char mQueryDisconnect[];
+    /* Start video capturing. */
+    static const char mQueryStart[];
+    /* Stop video capturing. */
+    static const char mQueryStop[];
+    /* Query frame(s). */
+    static const char mQueryFrame[];
+};
+
+}; /* namespace android */
+
+#endif  /* HW_EMULATOR_CAMERA_QEMU_CLIENT_H */
diff --git a/camera/fake-pipeline2/Base.h b/camera/fake-pipeline2/Base.h
new file mode 100644
index 0000000..057629b
--- /dev/null
+++ b/camera/fake-pipeline2/Base.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 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.
+ */
+
+/**
+ * This file includes various basic structures that are needed by multiple parts
+ * of the fake camera 2 implementation.
+ */
+
+#ifndef HW_EMULATOR_CAMERA2_BASE_H
+#define HW_EMULATOR_CAMERA2_BASE_H
+
+#include <system/window.h>
+#include <hardware/camera2.h>
+#include <utils/Vector.h>
+
+namespace android {
+
+
+/* Internal structure for passing buffers across threads */
+struct StreamBuffer {
+    // Positive numbers are output streams
+    // Negative numbers are input reprocess streams
+    // Zero is an auxillary buffer
+    int streamId;
+    uint32_t width, height;
+    uint32_t format;
+    uint32_t stride;
+    buffer_handle_t *buffer;
+    uint8_t *img;
+};
+typedef Vector<StreamBuffer> Buffers;
+
+struct Stream {
+    const camera2_stream_ops_t *ops;
+    uint32_t width, height;
+    int32_t format;
+    uint32_t stride;
+};
+
+struct ReprocessStream {
+    const camera2_stream_in_ops_t *ops;
+    uint32_t width, height;
+    int32_t format;
+    uint32_t stride;
+    // -1 if the reprocessing stream is independent
+    int32_t sourceStreamId;
+};
+
+} // namespace android;
+
+#endif
diff --git a/camera/fake-pipeline2/JpegCompressor.cpp b/camera/fake-pipeline2/JpegCompressor.cpp
new file mode 100644
index 0000000..20b9634
--- /dev/null
+++ b/camera/fake-pipeline2/JpegCompressor.cpp
@@ -0,0 +1,270 @@
+/*
+ * Copyright (C) 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.
+ */
+
+#define LOG_NDEBUG 0
+#define LOG_TAG "EmulatedCamera2_JpegCompressor"
+
+#include <utils/Log.h>
+#include <ui/GraphicBufferMapper.h>
+
+#include "JpegCompressor.h"
+#include "../EmulatedFakeCamera2.h"
+
+namespace android {
+
+JpegCompressor::JpegCompressor(EmulatedFakeCamera2 *parent):
+        Thread(false),
+        mIsBusy(false),
+        mParent(parent),
+        mBuffers(NULL),
+        mCaptureTime(0) {
+}
+
+JpegCompressor::~JpegCompressor() {
+    Mutex::Autolock lock(mMutex);
+}
+
+status_t JpegCompressor::start(Buffers *buffers,
+        nsecs_t captureTime) {
+    Mutex::Autolock lock(mMutex);
+    {
+        Mutex::Autolock busyLock(mBusyMutex);
+
+        if (mIsBusy) {
+            ALOGE("%s: Already processing a buffer!", __FUNCTION__);
+            return INVALID_OPERATION;
+        }
+
+        mIsBusy = true;
+
+        mBuffers = buffers;
+        mCaptureTime = captureTime;
+    }
+
+    status_t res;
+    res = run("EmulatedFakeCamera2::JpegCompressor");
+    if (res != OK) {
+        ALOGE("%s: Unable to start up compression thread: %s (%d)",
+                __FUNCTION__, strerror(-res), res);
+        delete mBuffers;
+    }
+    return res;
+}
+
+status_t JpegCompressor::cancel() {
+    requestExitAndWait();
+    return OK;
+}
+
+status_t JpegCompressor::readyToRun() {
+    return OK;
+}
+
+bool JpegCompressor::threadLoop() {
+    Mutex::Autolock lock(mMutex);
+    ALOGV("%s: Starting compression thread", __FUNCTION__);
+
+    // Find source and target buffers. Assumes only one buffer matches
+    // each condition!
+
+    bool foundJpeg = false, mFoundAux = false;
+    for (size_t i = 0; i < mBuffers->size(); i++) {
+        const StreamBuffer &b = (*mBuffers)[i];
+        if (b.format == HAL_PIXEL_FORMAT_BLOB) {
+            mJpegBuffer = b;
+            mFoundJpeg = true;
+        } else if (b.streamId <= 0) {
+            mAuxBuffer = b;
+            mFoundAux = true;
+        }
+        if (mFoundJpeg && mFoundAux) break;
+    }
+    if (!mFoundJpeg || !mFoundAux) {
+        ALOGE("%s: Unable to find buffers for JPEG source/destination",
+                __FUNCTION__);
+        cleanUp();
+        return false;
+    }
+
+    // Set up error management
+
+    mJpegErrorInfo = NULL;
+    JpegError error;
+    error.parent = this;
+
+    mCInfo.err = jpeg_std_error(&error);
+    mCInfo.err->error_exit = jpegErrorHandler;
+
+    jpeg_create_compress(&mCInfo);
+    if (checkError("Error initializing compression")) return false;
+
+    // Route compressed data straight to output stream buffer
+
+    JpegDestination jpegDestMgr;
+    jpegDestMgr.parent = this;
+    jpegDestMgr.init_destination = jpegInitDestination;
+    jpegDestMgr.empty_output_buffer = jpegEmptyOutputBuffer;
+    jpegDestMgr.term_destination = jpegTermDestination;
+
+    mCInfo.dest = &jpegDestMgr;
+
+    // Set up compression parameters
+
+    mCInfo.image_width = mAuxBuffer.width;
+    mCInfo.image_height = mAuxBuffer.height;
+    mCInfo.input_components = 3;
+    mCInfo.in_color_space = JCS_RGB;
+
+    jpeg_set_defaults(&mCInfo);
+    if (checkError("Error configuring defaults")) return false;
+
+    // Do compression
+
+    jpeg_start_compress(&mCInfo, TRUE);
+    if (checkError("Error starting compression")) return false;
+
+    size_t rowStride = mAuxBuffer.stride * 3;
+    const size_t kChunkSize = 32;
+    while (mCInfo.next_scanline < mCInfo.image_height) {
+        JSAMPROW chunk[kChunkSize];
+        for (size_t i = 0 ; i < kChunkSize; i++) {
+            chunk[i] = (JSAMPROW)
+                    (mAuxBuffer.img + (i + mCInfo.next_scanline) * rowStride);
+        }
+        jpeg_write_scanlines(&mCInfo, chunk, kChunkSize);
+        if (checkError("Error while compressing")) return false;
+        if (exitPending()) {
+            ALOGV("%s: Cancel called, exiting early", __FUNCTION__);
+            cleanUp();
+            return false;
+        }
+    }
+
+    jpeg_finish_compress(&mCInfo);
+    if (checkError("Error while finishing compression")) return false;
+
+    // Write to JPEG output stream
+
+    ALOGV("%s: Compression complete, pushing to stream %d", __FUNCTION__,
+          mJpegBuffer.streamId);
+
+    GraphicBufferMapper::get().unlock(*(mJpegBuffer.buffer));
+    status_t res;
+    const Stream &s = mParent->getStreamInfo(mJpegBuffer.streamId);
+    res = s.ops->enqueue_buffer(s.ops, mCaptureTime, mJpegBuffer.buffer);
+    if (res != OK) {
+        ALOGE("%s: Error queueing compressed image buffer %p: %s (%d)",
+                __FUNCTION__, mJpegBuffer.buffer, strerror(-res), res);
+        mParent->signalError();
+    }
+
+    // All done
+
+    cleanUp();
+
+    return false;
+}
+
+bool JpegCompressor::isBusy() {
+    Mutex::Autolock busyLock(mBusyMutex);
+    return mIsBusy;
+}
+
+bool JpegCompressor::isStreamInUse(uint32_t id) {
+    Mutex::Autolock lock(mBusyMutex);
+
+    if (mBuffers && mIsBusy) {
+        for (size_t i = 0; i < mBuffers->size(); i++) {
+            if ( (*mBuffers)[i].streamId == (int)id ) return true;
+        }
+    }
+    return false;
+}
+
+bool JpegCompressor::waitForDone(nsecs_t timeout) {
+    Mutex::Autolock lock(mBusyMutex);
+    status_t res = OK;
+    if (mIsBusy) {
+        res = mDone.waitRelative(mBusyMutex, timeout);
+    }
+    return (res == OK);
+}
+
+bool JpegCompressor::checkError(const char *msg) {
+    if (mJpegErrorInfo) {
+        char errBuffer[JMSG_LENGTH_MAX];
+        mJpegErrorInfo->err->format_message(mJpegErrorInfo, errBuffer);
+        ALOGE("%s: %s: %s",
+                __FUNCTION__, msg, errBuffer);
+        cleanUp();
+        mJpegErrorInfo = NULL;
+        return true;
+    }
+    return false;
+}
+
+void JpegCompressor::cleanUp() {
+    status_t res;
+    jpeg_destroy_compress(&mCInfo);
+    Mutex::Autolock lock(mBusyMutex);
+
+    if (mFoundAux) {
+        if (mAuxBuffer.streamId == 0) {
+            delete[] mAuxBuffer.img;
+        } else {
+            GraphicBufferMapper::get().unlock(*(mAuxBuffer.buffer));
+            const ReprocessStream &s =
+                    mParent->getReprocessStreamInfo(-mAuxBuffer.streamId);
+            res = s.ops->release_buffer(s.ops, mAuxBuffer.buffer);
+            if (res != OK) {
+                ALOGE("Error releasing reprocess buffer %p: %s (%d)",
+                        mAuxBuffer.buffer, strerror(-res), res);
+                mParent->signalError();
+            }
+        }
+    }
+    delete mBuffers;
+    mBuffers = NULL;
+
+    mIsBusy = false;
+    mDone.signal();
+}
+
+void JpegCompressor::jpegErrorHandler(j_common_ptr cinfo) {
+    JpegError *error = static_cast<JpegError*>(cinfo->err);
+    error->parent->mJpegErrorInfo = cinfo;
+}
+
+void JpegCompressor::jpegInitDestination(j_compress_ptr cinfo) {
+    JpegDestination *dest= static_cast<JpegDestination*>(cinfo->dest);
+    ALOGV("%s: Setting destination to %p, size %d",
+            __FUNCTION__, dest->parent->mJpegBuffer.img, kMaxJpegSize);
+    dest->next_output_byte = (JOCTET*)(dest->parent->mJpegBuffer.img);
+    dest->free_in_buffer = kMaxJpegSize;
+}
+
+boolean JpegCompressor::jpegEmptyOutputBuffer(j_compress_ptr cinfo) {
+    ALOGE("%s: JPEG destination buffer overflow!",
+            __FUNCTION__);
+    return true;
+}
+
+void JpegCompressor::jpegTermDestination(j_compress_ptr cinfo) {
+    ALOGV("%s: Done writing JPEG data. %d bytes left in buffer",
+            __FUNCTION__, cinfo->dest->free_in_buffer);
+}
+
+} // namespace android
diff --git a/camera/fake-pipeline2/JpegCompressor.h b/camera/fake-pipeline2/JpegCompressor.h
new file mode 100644
index 0000000..ea2a84f
--- /dev/null
+++ b/camera/fake-pipeline2/JpegCompressor.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 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.
+ */
+
+
+/**
+ * This class simulates a hardware JPEG compressor.  It receives image buffers
+ * in RGBA_8888 format, processes them in a worker thread, and then pushes them
+ * out to their destination stream.
+ */
+
+#ifndef HW_EMULATOR_CAMERA2_JPEG_H
+#define HW_EMULATOR_CAMERA2_JPEG_H
+
+#include "utils/Thread.h"
+#include "utils/Mutex.h"
+#include "utils/Timers.h"
+
+#include "Base.h"
+
+#include <stdio.h>
+
+extern "C" {
+#include <jpeglib.h>
+}
+
+namespace android {
+
+class EmulatedFakeCamera2;
+
+class JpegCompressor: private Thread, public virtual RefBase {
+  public:
+
+    JpegCompressor(EmulatedFakeCamera2 *parent);
+    ~JpegCompressor();
+
+    // Start compressing COMPRESSED format buffers; JpegCompressor takes
+    // ownership of the Buffers vector.
+    status_t start(Buffers *buffers,
+            nsecs_t captureTime);
+
+    status_t cancel();
+
+    bool isBusy();
+    bool isStreamInUse(uint32_t id);
+
+    bool waitForDone(nsecs_t timeout);
+
+    // TODO: Measure this
+    static const size_t kMaxJpegSize = 300000;
+
+  private:
+    Mutex mBusyMutex;
+    bool mIsBusy;
+    Condition mDone;
+
+    Mutex mMutex;
+
+    EmulatedFakeCamera2 *mParent;
+
+    Buffers *mBuffers;
+    nsecs_t mCaptureTime;
+
+    StreamBuffer mJpegBuffer, mAuxBuffer;
+    bool mFoundJpeg, mFoundAux;
+
+    jpeg_compress_struct mCInfo;
+
+    struct JpegError : public jpeg_error_mgr {
+        JpegCompressor *parent;
+    };
+    j_common_ptr mJpegErrorInfo;
+
+    struct JpegDestination : public jpeg_destination_mgr {
+        JpegCompressor *parent;
+    };
+
+    static void jpegErrorHandler(j_common_ptr cinfo);
+
+    static void jpegInitDestination(j_compress_ptr cinfo);
+    static boolean jpegEmptyOutputBuffer(j_compress_ptr cinfo);
+    static void jpegTermDestination(j_compress_ptr cinfo);
+
+    bool checkError(const char *msg);
+    void cleanUp();
+
+    /**
+     * Inherited Thread virtual overrides
+     */
+  private:
+    virtual status_t readyToRun();
+    virtual bool threadLoop();
+};
+
+} // namespace android
+
+#endif
diff --git a/camera/fake-pipeline2/Scene.cpp b/camera/fake-pipeline2/Scene.cpp
new file mode 100644
index 0000000..ca50350
--- /dev/null
+++ b/camera/fake-pipeline2/Scene.cpp
@@ -0,0 +1,459 @@
+/*
+ * Copyright (C) 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "EmulatedCamera_Scene"
+#include <utils/Log.h>
+#include <stdlib.h>
+
+#include "Scene.h"
+
+// TODO: This should probably be done host-side in OpenGL for speed and better
+// quality
+
+namespace android {
+
+// Define single-letter shortcuts for scene definition, for directly indexing
+// mCurrentColors
+#define G (Scene::GRASS * Scene::NUM_CHANNELS)
+#define S (Scene::GRASS_SHADOW * Scene::NUM_CHANNELS)
+#define H (Scene::HILL * Scene::NUM_CHANNELS)
+#define W (Scene::WALL * Scene::NUM_CHANNELS)
+#define R (Scene::ROOF * Scene::NUM_CHANNELS)
+#define D (Scene::DOOR * Scene::NUM_CHANNELS)
+#define C (Scene::CHIMNEY * Scene::NUM_CHANNELS)
+#define I (Scene::WINDOW * Scene::NUM_CHANNELS)
+#define U (Scene::SUN * Scene::NUM_CHANNELS)
+#define K (Scene::SKY * Scene::NUM_CHANNELS)
+#define M (Scene::MOON * Scene::NUM_CHANNELS)
+
+const int Scene::kSceneWidth = 20;
+const int Scene::kSceneHeight = 20;
+
+const uint8_t Scene::kScene[Scene::kSceneWidth * Scene::kSceneHeight] = {
+    //      5         10        15        20
+    K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,
+    K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,
+    K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,
+    K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,
+    K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K, // 5
+    K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,
+    K,K,K,K,K,K,K,K,H,H,H,H,H,H,H,H,H,H,H,H,
+    K,K,K,K,K,K,K,K,H,H,H,H,H,H,H,C,C,H,H,H,
+    K,K,K,K,K,K,H,H,H,H,H,H,H,H,H,C,C,H,H,H,
+    H,K,K,K,K,K,H,R,R,R,R,R,R,R,R,R,R,R,R,H, // 10
+    H,K,K,K,K,H,H,R,R,R,R,R,R,R,R,R,R,R,R,H,
+    H,H,H,K,K,H,H,R,R,R,R,R,R,R,R,R,R,R,R,H,
+    H,H,H,K,K,H,H,H,W,W,W,W,W,W,W,W,W,W,H,H,
+    S,S,S,G,G,S,S,S,W,W,W,W,W,W,W,W,W,W,S,S,
+    S,G,G,G,G,S,S,S,W,I,I,W,D,D,W,I,I,W,S,S, // 15
+    G,G,G,G,G,G,S,S,W,I,I,W,D,D,W,I,I,W,S,S,
+    G,G,G,G,G,G,G,G,W,W,W,W,D,D,W,W,W,W,G,G,
+    G,G,G,G,G,G,G,G,W,W,W,W,D,D,W,W,W,W,G,G,
+    G,G,G,G,G,G,G,G,S,S,S,S,S,S,S,S,S,S,G,G,
+    G,G,G,G,G,G,G,G,S,S,S,S,S,S,S,S,S,S,G,G, // 20
+    //      5         10        15        20
+};
+
+#undef G
+#undef S
+#undef H
+#undef W
+#undef R
+#undef D
+#undef C
+#undef I
+#undef U
+#undef K
+#undef M
+
+Scene::Scene(
+    int sensorWidthPx,
+    int sensorHeightPx,
+    float sensorSensitivity):
+        mSensorWidth(sensorWidthPx),
+        mSensorHeight(sensorHeightPx),
+        mHour(12),
+        mExposureDuration(0.033f),
+        mSensorSensitivity(sensorSensitivity)
+{
+    // Map scene to sensor pixels
+    if (mSensorWidth > mSensorHeight) {
+        mMapDiv = (mSensorWidth / (kSceneWidth + 1) ) + 1;
+    } else {
+        mMapDiv = (mSensorHeight / (kSceneHeight + 1) ) + 1;
+    }
+    mOffsetX = (kSceneWidth * mMapDiv - mSensorWidth) / 2;
+    mOffsetY = (kSceneHeight * mMapDiv - mSensorHeight) / 2;
+
+    // Assume that sensor filters are sRGB primaries to start
+    mFilterR[0]  =  3.2406f; mFilterR[1]  = -1.5372f; mFilterR[2]  = -0.4986f;
+    mFilterGr[0] = -0.9689f; mFilterGr[1] =  1.8758f; mFilterGr[2] =  0.0415f;
+    mFilterGb[0] = -0.9689f; mFilterGb[1] =  1.8758f; mFilterGb[2] =  0.0415f;
+    mFilterB[0]  =  0.0557f; mFilterB[1]  = -0.2040f; mFilterB[2]  =  1.0570f;
+
+
+}
+
+Scene::~Scene() {
+}
+
+void Scene::setColorFilterXYZ(
+        float rX, float rY, float rZ,
+        float grX, float grY, float grZ,
+        float gbX, float gbY, float gbZ,
+        float bX, float bY, float bZ) {
+    mFilterR[0]  = rX;  mFilterR[1]  = rY;  mFilterR[2]  = rZ;
+    mFilterGr[0] = grX; mFilterGr[1] = grY; mFilterGr[2] = grZ;
+    mFilterGb[0] = gbX; mFilterGb[1] = gbY; mFilterGb[2] = gbZ;
+    mFilterB[0]  = bX;  mFilterB[1]  = bY;  mFilterB[2]  = bZ;
+}
+
+void Scene::setHour(int hour) {
+    ALOGV("Hour set to: %d", hour);
+    mHour = hour % 24;
+}
+
+int Scene::getHour() {
+    return mHour;
+}
+
+void Scene::setExposureDuration(float seconds) {
+    mExposureDuration = seconds;
+}
+
+void Scene::calculateScene(nsecs_t time) {
+    // Calculate time fractions for interpolation
+    int timeIdx = mHour / kTimeStep;
+    int nextTimeIdx = (timeIdx + 1) % (24 / kTimeStep);
+    const nsecs_t kOneHourInNsec = 1e9 * 60 * 60;
+    nsecs_t timeSinceIdx = (mHour - timeIdx * kTimeStep) * kOneHourInNsec + time;
+    float timeFrac = timeSinceIdx / (float)(kOneHourInNsec * kTimeStep);
+
+    // Determine overall sunlight levels
+    float sunLux =
+            kSunlight[timeIdx] * (1 - timeFrac) +
+            kSunlight[nextTimeIdx] * timeFrac;
+    ALOGV("Sun lux: %f", sunLux);
+
+    float sunShadeLux = sunLux * (kDaylightShadeIllum / kDirectSunIllum);
+
+    // Determine sun/shade illumination chromaticity
+    float currentSunXY[2];
+    float currentShadeXY[2];
+
+    const float *prevSunXY, *nextSunXY;
+    const float *prevShadeXY, *nextShadeXY;
+    if (kSunlight[timeIdx] == kSunsetIllum ||
+            kSunlight[timeIdx] == kTwilightIllum) {
+        prevSunXY = kSunsetXY;
+        prevShadeXY = kSunsetXY;
+    } else {
+        prevSunXY = kDirectSunlightXY;
+        prevShadeXY = kDaylightXY;
+    }
+    if (kSunlight[nextTimeIdx] == kSunsetIllum ||
+            kSunlight[nextTimeIdx] == kTwilightIllum) {
+        nextSunXY = kSunsetXY;
+        nextShadeXY = kSunsetXY;
+    } else {
+        nextSunXY = kDirectSunlightXY;
+        nextShadeXY = kDaylightXY;
+    }
+    currentSunXY[0] = prevSunXY[0] * (1 - timeFrac) +
+            nextSunXY[0] * timeFrac;
+    currentSunXY[1] = prevSunXY[1] * (1 - timeFrac) +
+            nextSunXY[1] * timeFrac;
+
+    currentShadeXY[0] = prevShadeXY[0] * (1 - timeFrac) +
+            nextShadeXY[0] * timeFrac;
+    currentShadeXY[1] = prevShadeXY[1] * (1 - timeFrac) +
+            nextShadeXY[1] * timeFrac;
+
+    ALOGV("Sun XY: %f, %f, Shade XY: %f, %f",
+            currentSunXY[0], currentSunXY[1],
+            currentShadeXY[0], currentShadeXY[1]);
+
+    // Converting for xyY to XYZ:
+    // X = Y / y * x
+    // Y = Y
+    // Z = Y / y * (1 - x - y);
+    float sunXYZ[3] = {
+        sunLux / currentSunXY[1] * currentSunXY[0],
+        sunLux,
+        sunLux / currentSunXY[1] *
+        (1 - currentSunXY[0] - currentSunXY[1])
+    };
+    float sunShadeXYZ[3] = {
+        sunShadeLux / currentShadeXY[1] * currentShadeXY[0],
+        sunShadeLux,
+        sunShadeLux / currentShadeXY[1] *
+        (1 - currentShadeXY[0] - currentShadeXY[1])
+    };
+    ALOGV("Sun XYZ: %f, %f, %f",
+            sunXYZ[0], sunXYZ[1], sunXYZ[2]);
+    ALOGV("Sun shade XYZ: %f, %f, %f",
+            sunShadeXYZ[0], sunShadeXYZ[1], sunShadeXYZ[2]);
+
+    // Determine moonlight levels
+    float moonLux =
+            kMoonlight[timeIdx] * (1 - timeFrac) +
+            kMoonlight[nextTimeIdx] * timeFrac;
+    float moonShadeLux = moonLux * (kDaylightShadeIllum / kDirectSunIllum);
+
+    float moonXYZ[3] = {
+        moonLux / kMoonlightXY[1] * kMoonlightXY[0],
+        moonLux,
+        moonLux / kMoonlightXY[1] *
+        (1 - kMoonlightXY[0] - kMoonlightXY[1])
+    };
+    float moonShadeXYZ[3] = {
+        moonShadeLux / kMoonlightXY[1] * kMoonlightXY[0],
+        moonShadeLux,
+        moonShadeLux / kMoonlightXY[1] *
+        (1 - kMoonlightXY[0] - kMoonlightXY[1])
+    };
+
+    // Determine starlight level
+    const float kClearNightXYZ[3] = {
+        kClearNightIllum / kMoonlightXY[1] * kMoonlightXY[0],
+        kClearNightIllum,
+        kClearNightIllum / kMoonlightXY[1] *
+            (1 - kMoonlightXY[0] - kMoonlightXY[1])
+    };
+
+    // Calculate direct and shaded light
+    float directIllumXYZ[3] = {
+        sunXYZ[0] + moonXYZ[0] + kClearNightXYZ[0],
+        sunXYZ[1] + moonXYZ[1] + kClearNightXYZ[1],
+        sunXYZ[2] + moonXYZ[2] + kClearNightXYZ[2],
+    };
+
+    float shadeIllumXYZ[3] = {
+        kClearNightXYZ[0],
+        kClearNightXYZ[1],
+        kClearNightXYZ[2]
+    };
+
+    shadeIllumXYZ[0] += (mHour < kSunOverhead) ? sunXYZ[0] : sunShadeXYZ[0];
+    shadeIllumXYZ[1] += (mHour < kSunOverhead) ? sunXYZ[1] : sunShadeXYZ[1];
+    shadeIllumXYZ[2] += (mHour < kSunOverhead) ? sunXYZ[2] : sunShadeXYZ[2];
+
+    // Moon up period covers 23->0 transition, shift for simplicity
+    int adjHour = (mHour + 12) % 24;
+    int adjMoonOverhead = (kMoonOverhead + 12 ) % 24;
+    shadeIllumXYZ[0] += (adjHour < adjMoonOverhead) ?
+            moonXYZ[0] : moonShadeXYZ[0];
+    shadeIllumXYZ[1] += (adjHour < adjMoonOverhead) ?
+            moonXYZ[1] : moonShadeXYZ[1];
+    shadeIllumXYZ[2] += (adjHour < adjMoonOverhead) ?
+            moonXYZ[2] : moonShadeXYZ[2];
+
+    ALOGV("Direct XYZ: %f, %f, %f",
+            directIllumXYZ[0],directIllumXYZ[1],directIllumXYZ[2]);
+    ALOGV("Shade XYZ: %f, %f, %f",
+            shadeIllumXYZ[0], shadeIllumXYZ[1], shadeIllumXYZ[2]);
+
+    for (int i = 0; i < NUM_MATERIALS; i++) {
+        // Converting for xyY to XYZ:
+        // X = Y / y * x
+        // Y = Y
+        // Z = Y / y * (1 - x - y);
+        float matXYZ[3] = {
+            kMaterials_xyY[i][2] / kMaterials_xyY[i][1] *
+              kMaterials_xyY[i][0],
+            kMaterials_xyY[i][2],
+            kMaterials_xyY[i][2] / kMaterials_xyY[i][1] *
+              (1 - kMaterials_xyY[i][0] - kMaterials_xyY[i][1])
+        };
+
+        if (kMaterialsFlags[i] == 0 || kMaterialsFlags[i] & kSky) {
+            matXYZ[0] *= directIllumXYZ[0];
+            matXYZ[1] *= directIllumXYZ[1];
+            matXYZ[2] *= directIllumXYZ[2];
+        } else if (kMaterialsFlags[i] & kShadowed) {
+            matXYZ[0] *= shadeIllumXYZ[0];
+            matXYZ[1] *= shadeIllumXYZ[1];
+            matXYZ[2] *= shadeIllumXYZ[2];
+        } // else if (kMaterialsFlags[i] * kSelfLit), do nothing
+
+        ALOGV("Mat %d XYZ: %f, %f, %f", i, matXYZ[0], matXYZ[1], matXYZ[2]);
+        float luxToElectrons = mSensorSensitivity * mExposureDuration /
+                (kAperture * kAperture);
+        mCurrentColors[i*NUM_CHANNELS + 0] =
+                (mFilterR[0] * matXYZ[0] +
+                 mFilterR[1] * matXYZ[1] +
+                 mFilterR[2] * matXYZ[2])
+                * luxToElectrons;
+        mCurrentColors[i*NUM_CHANNELS + 1] =
+                (mFilterGr[0] * matXYZ[0] +
+                 mFilterGr[1] * matXYZ[1] +
+                 mFilterGr[2] * matXYZ[2])
+                * luxToElectrons;
+        mCurrentColors[i*NUM_CHANNELS + 2] =
+                (mFilterGb[0] * matXYZ[0] +
+                 mFilterGb[1] * matXYZ[1] +
+                 mFilterGb[2] * matXYZ[2])
+                * luxToElectrons;
+        mCurrentColors[i*NUM_CHANNELS + 3] =
+                (mFilterB[0] * matXYZ[0] +
+                 mFilterB[1] * matXYZ[1] +
+                 mFilterB[2] * matXYZ[2])
+                * luxToElectrons;
+
+        ALOGV("Color %d RGGB: %d, %d, %d, %d", i,
+                mCurrentColors[i*NUM_CHANNELS + 0],
+                mCurrentColors[i*NUM_CHANNELS + 1],
+                mCurrentColors[i*NUM_CHANNELS + 2],
+                mCurrentColors[i*NUM_CHANNELS + 3]);
+    }
+    // Shake viewpoint
+    mHandshakeX = rand() % mMapDiv/4 - mMapDiv/8;
+    mHandshakeY = rand() % mMapDiv/4 - mMapDiv/8;
+    // Set starting pixel
+    setReadoutPixel(0,0);
+}
+
+void Scene::setReadoutPixel(int x, int y) {
+    mCurrentX = x;
+    mCurrentY = y;
+    mSubX = (x + mOffsetX + mHandshakeX) % mMapDiv;
+    mSubY = (y + mOffsetY + mHandshakeY) % mMapDiv;
+    mSceneX = (x + mOffsetX + mHandshakeX) / mMapDiv;
+    mSceneY = (y + mOffsetY + mHandshakeY) / mMapDiv;
+    mSceneIdx = mSceneY * kSceneWidth + mSceneX;
+    mCurrentSceneMaterial = &(mCurrentColors[kScene[mSceneIdx]]);
+}
+
+const uint32_t* Scene::getPixelElectrons() {
+    const uint32_t *pixel = mCurrentSceneMaterial;
+    mCurrentX++;
+    mSubX++;
+    if (mCurrentX >= mSensorWidth) {
+        mCurrentX = 0;
+        mCurrentY++;
+        if (mCurrentY >= mSensorHeight) mCurrentY = 0;
+        setReadoutPixel(mCurrentX, mCurrentY);
+    } else if (mSubX > mMapDiv) {
+        mSceneIdx++;
+        mSceneX++;
+        mCurrentSceneMaterial = &(mCurrentColors[kScene[mSceneIdx]]);
+        mSubX = 0;
+    }
+    return pixel;
+}
+
+// RGB->YUV, Jpeg standard
+const float Scene::kRgb2Yuv[12] = {
+       0.299f,    0.587f,    0.114f,    0.f,
+    -0.16874f, -0.33126f,      0.5f, -128.f,
+         0.5f, -0.41869f, -0.08131f, -128.f,
+};
+
+// Aperture of imaging lens
+const float Scene::kAperture = 2.8;
+
+// Sun illumination levels through the day
+const float Scene::kSunlight[24/kTimeStep] =
+{
+    0, // 00:00
+    0,
+    0,
+    kTwilightIllum, // 06:00
+    kDirectSunIllum,
+    kDirectSunIllum,
+    kDirectSunIllum, // 12:00
+    kDirectSunIllum,
+    kDirectSunIllum,
+    kSunsetIllum, // 18:00
+    kTwilightIllum,
+    0
+};
+
+// Moon illumination levels through the day
+const float Scene::kMoonlight[24/kTimeStep] =
+{
+    kFullMoonIllum, // 00:00
+    kFullMoonIllum,
+    0,
+    0, // 06:00
+    0,
+    0,
+    0, // 12:00
+    0,
+    0,
+    0, // 18:00
+    0,
+    kFullMoonIllum
+};
+
+const int Scene::kSunOverhead = 12;
+const int Scene::kMoonOverhead = 0;
+
+// Used for sun illumination levels
+const float Scene::kDirectSunIllum     = 100000;
+const float Scene::kSunsetIllum        = 400;
+const float Scene::kTwilightIllum      = 4;
+// Used for moon illumination levels
+const float Scene::kFullMoonIllum      = 1;
+// Other illumination levels
+const float Scene::kDaylightShadeIllum = 20000;
+const float Scene::kClearNightIllum    = 2e-3;
+const float Scene::kStarIllum          = 2e-6;
+const float Scene::kLivingRoomIllum    = 50;
+
+const float Scene::kIncandescentXY[2]   = { 0.44757f, 0.40745f};
+const float Scene::kDirectSunlightXY[2] = { 0.34842f, 0.35161f};
+const float Scene::kDaylightXY[2]       = { 0.31271f, 0.32902f};
+const float Scene::kNoonSkyXY[2]        = { 0.346f,   0.359f};
+const float Scene::kMoonlightXY[2]      = { 0.34842f, 0.35161f};
+const float Scene::kSunsetXY[2]         = { 0.527f,   0.413f};
+
+const uint8_t Scene::kSelfLit  = 0x01;
+const uint8_t Scene::kShadowed = 0x02;
+const uint8_t Scene::kSky      = 0x04;
+
+// For non-self-lit materials, the Y component is normalized with 1=full
+// reflectance; for self-lit materials, it's the constant illuminance in lux.
+const float Scene::kMaterials_xyY[Scene::NUM_MATERIALS][3] = {
+    { 0.3688f, 0.4501f, .1329f }, // GRASS
+    { 0.3688f, 0.4501f, .1329f }, // GRASS_SHADOW
+    { 0.3986f, 0.5002f, .4440f }, // HILL
+    { 0.3262f, 0.5040f, .2297f }, // WALL
+    { 0.4336f, 0.3787f, .1029f }, // ROOF
+    { 0.3316f, 0.2544f, .0639f }, // DOOR
+    { 0.3425f, 0.3577f, .0887f }, // CHIMNEY
+    { kIncandescentXY[0], kIncandescentXY[1], kLivingRoomIllum }, // WINDOW
+    { kDirectSunlightXY[0], kDirectSunlightXY[1], kDirectSunIllum }, // SUN
+    { kNoonSkyXY[0], kNoonSkyXY[1], kDaylightShadeIllum / kDirectSunIllum }, // SKY
+    { kMoonlightXY[0], kMoonlightXY[1], kFullMoonIllum } // MOON
+};
+
+const uint8_t Scene::kMaterialsFlags[Scene::NUM_MATERIALS] = {
+    0,
+    kShadowed,
+    kShadowed,
+    kShadowed,
+    kShadowed,
+    kShadowed,
+    kShadowed,
+    kSelfLit,
+    kSelfLit,
+    kSky,
+    kSelfLit,
+};
+
+} // namespace android
diff --git a/camera/fake-pipeline2/Scene.h b/camera/fake-pipeline2/Scene.h
new file mode 100644
index 0000000..687e427
--- /dev/null
+++ b/camera/fake-pipeline2/Scene.h
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 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.
+ */
+
+/**
+ * The Scene class implements a simple physical simulation of a scene, using the
+ * CIE 1931 colorspace to represent light in physical units (lux).
+ *
+ * It's fairly approximate, but does provide a scene with realistic widely
+ * variable illumination levels and colors over time.
+ *
+ */
+
+#ifndef HW_EMULATOR_CAMERA2_SCENE_H
+#define HW_EMULATOR_CAMERA2_SCENE_H
+
+#include "utils/Timers.h"
+
+namespace android {
+
+class Scene {
+  public:
+    Scene(int sensorWidthPx,
+            int sensorHeightPx,
+            float sensorSensitivity);
+    ~Scene();
+
+    // Set the filter coefficients for the red, green, and blue filters on the
+    // sensor. Used as an optimization to pre-calculate various illuminance
+    // values. Two different green filters can be provided, to account for
+    // possible cross-talk on a Bayer sensor. Must be called before
+    // calculateScene.
+    void setColorFilterXYZ(
+        float rX, float rY, float rZ,
+        float grX, float grY, float grZ,
+        float gbX, float gbY, float gbZ,
+        float bX, float bY, float bZ);
+
+    // Set time of day (24-hour clock). This controls the general light levels
+    // in the scene. Must be called before calculateScene
+    void setHour(int hour);
+    // Get current hour
+    int getHour();
+
+    // Set the duration of exposure for determining luminous exposure.
+    // Must be called before calculateScene
+    void setExposureDuration(float seconds);
+
+    // Calculate scene information for current hour and the time offset since
+    // the hour. Must be called at least once before calling getLuminousExposure.
+    // Resets pixel readout location to 0,0
+    void calculateScene(nsecs_t time);
+
+    // Set sensor pixel readout location.
+    void setReadoutPixel(int x, int y);
+
+    // Get sensor response in physical units (electrons) for light hitting the
+    // current readout pixel, after passing through color filters. The readout
+    // pixel will be auto-incremented. The returned array can be indexed with
+    // ColorChannels.
+    const uint32_t* getPixelElectrons();
+
+    enum ColorChannels {
+        R = 0,
+        Gr,
+        Gb,
+        B,
+        Y,
+        Cb,
+        Cr,
+        NUM_CHANNELS
+    };
+
+  private:
+    // Sensor color filtering coefficients in XYZ
+    float mFilterR[3];
+    float mFilterGr[3];
+    float mFilterGb[3];
+    float mFilterB[3];
+
+    int mOffsetX, mOffsetY;
+    int mMapDiv;
+
+    int mHandshakeX, mHandshakeY;
+
+    int mSensorWidth;
+    int mSensorHeight;
+    int mCurrentX;
+    int mCurrentY;
+    int mSubX;
+    int mSubY;
+    int mSceneX;
+    int mSceneY;
+    int mSceneIdx;
+    uint32_t *mCurrentSceneMaterial;
+
+    int mHour;
+    float mExposureDuration;
+    float mSensorSensitivity;
+
+    enum Materials {
+        GRASS = 0,
+        GRASS_SHADOW,
+        HILL,
+        WALL,
+        ROOF,
+        DOOR,
+        CHIMNEY,
+        WINDOW,
+        SUN,
+        SKY,
+        MOON,
+        NUM_MATERIALS
+    };
+
+    uint32_t mCurrentColors[NUM_MATERIALS*NUM_CHANNELS];
+
+    /**
+     * Constants for scene definition. These are various degrees of approximate.
+     */
+
+    // RGB->YUV conversion
+    static const float kRgb2Yuv[12];
+
+    // Aperture of imaging lens
+    static const float kAperture;
+
+    // Sun, moon illuminance levels in 2-hour increments. These don't match any
+    // real day anywhere.
+    static const uint32_t kTimeStep = 2;
+    static const float kSunlight[];
+    static const float kMoonlight[];
+    static const int kSunOverhead;
+    static const int kMoonOverhead;
+
+    // Illumination levels for various conditions, in lux
+    static const float kDirectSunIllum;
+    static const float kDaylightShadeIllum;
+    static const float kSunsetIllum;
+    static const float kTwilightIllum;
+    static const float kFullMoonIllum;
+    static const float kClearNightIllum;
+    static const float kStarIllum;
+    static const float kLivingRoomIllum;
+
+    // Chromaticity of various illumination sources
+    static const float kIncandescentXY[2];
+    static const float kDirectSunlightXY[2];
+    static const float kDaylightXY[2];
+    static const float kNoonSkyXY[2];
+    static const float kMoonlightXY[2];
+    static const float kSunsetXY[2];
+
+    static const uint8_t kSelfLit;
+    static const uint8_t kShadowed;
+    static const uint8_t kSky;
+
+    static const float kMaterials_xyY[NUM_MATERIALS][3];
+    static const uint8_t kMaterialsFlags[NUM_MATERIALS];
+
+    static const int kSceneWidth;
+    static const int kSceneHeight;
+    static const uint8_t kScene[];
+};
+
+}
+
+#endif // HW_EMULATOR_CAMERA2_SCENE_H
diff --git a/camera/fake-pipeline2/Sensor.cpp b/camera/fake-pipeline2/Sensor.cpp
new file mode 100644
index 0000000..316fe02
--- /dev/null
+++ b/camera/fake-pipeline2/Sensor.cpp
@@ -0,0 +1,501 @@
+/*
+ * Copyright (C) 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.
+ */
+
+//#define LOG_NDEBUG 0
+//#define LOG_NNDEBUG 0
+#define LOG_TAG "EmulatedCamera2_Sensor"
+
+#ifdef LOG_NNDEBUG
+#define ALOGVV(...) ALOGV(__VA_ARGS__)
+#else
+#define ALOGVV(...) ((void)0)
+#endif
+
+#include <utils/Log.h>
+
+#include "../EmulatedFakeCamera2.h"
+#include "Sensor.h"
+#include <cmath>
+#include <cstdlib>
+#include "system/camera_metadata.h"
+
+namespace android {
+
+const unsigned int Sensor::kResolution[2]  = {640, 480};
+
+const nsecs_t Sensor::kExposureTimeRange[2] =
+    {1000L, 30000000000L} ; // 1 us - 30 sec
+const nsecs_t Sensor::kFrameDurationRange[2] =
+    {33331760L, 30000000000L}; // ~1/30 s - 30 sec
+const nsecs_t Sensor::kMinVerticalBlank = 10000L;
+
+const uint8_t Sensor::kColorFilterArrangement =
+    ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGGB;
+
+// Output image data characteristics
+const uint32_t Sensor::kMaxRawValue = 4000;
+const uint32_t Sensor::kBlackLevel  = 1000;
+
+// Sensor sensitivity
+const float Sensor::kSaturationVoltage      = 0.520f;
+const uint32_t Sensor::kSaturationElectrons = 2000;
+const float Sensor::kVoltsPerLuxSecond      = 0.100f;
+
+const float Sensor::kElectronsPerLuxSecond =
+        Sensor::kSaturationElectrons / Sensor::kSaturationVoltage
+        * Sensor::kVoltsPerLuxSecond;
+
+const float Sensor::kBaseGainFactor = (float)Sensor::kMaxRawValue /
+            Sensor::kSaturationElectrons;
+
+const float Sensor::kReadNoiseStddevBeforeGain = 1.177; // in electrons
+const float Sensor::kReadNoiseStddevAfterGain =  2.100; // in digital counts
+const float Sensor::kReadNoiseVarBeforeGain =
+            Sensor::kReadNoiseStddevBeforeGain *
+            Sensor::kReadNoiseStddevBeforeGain;
+const float Sensor::kReadNoiseVarAfterGain =
+            Sensor::kReadNoiseStddevAfterGain *
+            Sensor::kReadNoiseStddevAfterGain;
+
+// While each row has to read out, reset, and then expose, the (reset +
+// expose) sequence can be overlapped by other row readouts, so the final
+// minimum frame duration is purely a function of row readout time, at least
+// if there's a reasonable number of rows.
+const nsecs_t Sensor::kRowReadoutTime =
+            Sensor::kFrameDurationRange[0] / Sensor::kResolution[1];
+
+const uint32_t Sensor::kAvailableSensitivities[5] =
+    {100, 200, 400, 800, 1600};
+const uint32_t Sensor::kDefaultSensitivity = 100;
+
+/** A few utility functions for math, normal distributions */
+
+// Take advantage of IEEE floating-point format to calculate an approximate
+// square root. Accurate to within +-3.6%
+float sqrtf_approx(float r) {
+    // Modifier is based on IEEE floating-point representation; the
+    // manipulations boil down to finding approximate log2, dividing by two, and
+    // then inverting the log2. A bias is added to make the relative error
+    // symmetric about the real answer.
+    const int32_t modifier = 0x1FBB4000;
+
+    int32_t r_i = *(int32_t*)(&r);
+    r_i = (r_i >> 1) + modifier;
+
+    return *(float*)(&r_i);
+}
+
+
+
+Sensor::Sensor(EmulatedFakeCamera2 *parent):
+        Thread(false),
+        mParent(parent),
+        mGotVSync(false),
+        mExposureTime(kFrameDurationRange[0]-kMinVerticalBlank),
+        mFrameDuration(kFrameDurationRange[0]),
+        mGainFactor(kDefaultSensitivity),
+        mNextBuffers(NULL),
+        mCapturedBuffers(NULL),
+        mScene(kResolution[0], kResolution[1], kElectronsPerLuxSecond)
+{
+
+}
+
+Sensor::~Sensor() {
+    shutDown();
+}
+
+status_t Sensor::startUp() {
+    ALOGV("%s: E", __FUNCTION__);
+
+    int res;
+    mCapturedBuffers = NULL;
+    res = run("EmulatedFakeCamera2::Sensor",
+            ANDROID_PRIORITY_URGENT_DISPLAY);
+
+    if (res != OK) {
+        ALOGE("Unable to start up sensor capture thread: %d", res);
+    }
+    return res;
+}
+
+status_t Sensor::shutDown() {
+    ALOGV("%s: E", __FUNCTION__);
+
+    int res;
+    res = requestExitAndWait();
+    if (res != OK) {
+        ALOGE("Unable to shut down sensor capture thread: %d", res);
+    }
+    return res;
+}
+
+Scene &Sensor::getScene() {
+    return mScene;
+}
+
+void Sensor::setExposureTime(uint64_t ns) {
+    Mutex::Autolock lock(mControlMutex);
+    ALOGVV("Exposure set to %f", ns/1000000.f);
+    mExposureTime = ns;
+}
+
+void Sensor::setFrameDuration(uint64_t ns) {
+    Mutex::Autolock lock(mControlMutex);
+    ALOGVV("Frame duration set to %f", ns/1000000.f);
+    mFrameDuration = ns;
+}
+
+void Sensor::setSensitivity(uint32_t gain) {
+    Mutex::Autolock lock(mControlMutex);
+    ALOGVV("Gain set to %d", gain);
+    mGainFactor = gain;
+}
+
+void Sensor::setDestinationBuffers(Buffers *buffers) {
+    Mutex::Autolock lock(mControlMutex);
+    mNextBuffers = buffers;
+}
+
+bool Sensor::waitForVSync(nsecs_t reltime) {
+    int res;
+    Mutex::Autolock lock(mControlMutex);
+
+    mGotVSync = false;
+    res = mVSync.waitRelative(mControlMutex, reltime);
+    if (res != OK && res != TIMED_OUT) {
+        ALOGE("%s: Error waiting for VSync signal: %d", __FUNCTION__, res);
+        return false;
+    }
+    return mGotVSync;
+}
+
+bool Sensor::waitForNewFrame(nsecs_t reltime,
+        nsecs_t *captureTime) {
+    Mutex::Autolock lock(mReadoutMutex);
+    uint8_t *ret;
+    if (mCapturedBuffers == NULL) {
+        int res;
+        res = mReadoutAvailable.waitRelative(mReadoutMutex, reltime);
+        if (res == TIMED_OUT) {
+            return false;
+        } else if (res != OK || mCapturedBuffers == NULL) {
+            ALOGE("Error waiting for sensor readout signal: %d", res);
+            return false;
+        }
+    } else {
+        mReadoutComplete.signal();
+    }
+
+    *captureTime = mCaptureTime;
+    mCapturedBuffers = NULL;
+    return true;
+}
+
+status_t Sensor::readyToRun() {
+    ALOGV("Starting up sensor thread");
+    mStartupTime = systemTime();
+    mNextCaptureTime = 0;
+    mNextCapturedBuffers = NULL;
+    return OK;
+}
+
+bool Sensor::threadLoop() {
+    /**
+     * Sensor capture operation main loop.
+     *
+     * Stages are out-of-order relative to a single frame's processing, but
+     * in-order in time.
+     */
+
+    /**
+     * Stage 1: Read in latest control parameters
+     */
+    uint64_t exposureDuration;
+    uint64_t frameDuration;
+    uint32_t gain;
+    Buffers *nextBuffers;
+    {
+        Mutex::Autolock lock(mControlMutex);
+        exposureDuration = mExposureTime;
+        frameDuration    = mFrameDuration;
+        gain             = mGainFactor;
+        nextBuffers      = mNextBuffers;
+        // Don't reuse a buffer set
+        mNextBuffers = NULL;
+
+        // Signal VSync for start of readout
+        ALOGVV("Sensor VSync");
+        mGotVSync = true;
+        mVSync.signal();
+    }
+
+    /**
+     * Stage 3: Read out latest captured image
+     */
+
+    Buffers *capturedBuffers = NULL;
+    nsecs_t captureTime = 0;
+
+    nsecs_t startRealTime  = systemTime();
+    // Stagefright cares about system time for timestamps, so base simulated
+    // time on that.
+    nsecs_t simulatedTime    = startRealTime;
+    nsecs_t frameEndRealTime = startRealTime + frameDuration;
+    nsecs_t frameReadoutEndRealTime = startRealTime +
+            kRowReadoutTime * kResolution[1];
+
+    if (mNextCapturedBuffers != NULL) {
+        ALOGVV("Sensor starting readout");
+        // Pretend we're doing readout now; will signal once enough time has elapsed
+        capturedBuffers = mNextCapturedBuffers;
+        captureTime    = mNextCaptureTime;
+    }
+    simulatedTime += kRowReadoutTime + kMinVerticalBlank;
+
+    // TODO: Move this signal to another thread to simulate readout
+    // time properly
+    if (capturedBuffers != NULL) {
+        ALOGVV("Sensor readout complete");
+        Mutex::Autolock lock(mReadoutMutex);
+        if (mCapturedBuffers != NULL) {
+            ALOGV("Waiting for readout thread to catch up!");
+            mReadoutComplete.wait(mReadoutMutex);
+        }
+
+        mCapturedBuffers = capturedBuffers;
+        mCaptureTime = captureTime;
+        mReadoutAvailable.signal();
+        capturedBuffers = NULL;
+    }
+
+    /**
+     * Stage 2: Capture new image
+     */
+
+    mNextCaptureTime = simulatedTime;
+    mNextCapturedBuffers = nextBuffers;
+
+    if (mNextCapturedBuffers != NULL) {
+        ALOGVV("Starting next capture: Exposure: %f ms, gain: %d",
+                (float)exposureDuration/1e6, gain);
+        mScene.setExposureDuration((float)exposureDuration/1e9);
+        mScene.calculateScene(mNextCaptureTime);
+
+        // Might be adding more buffers, so size isn't constant
+        for (size_t i = 0; i < mNextCapturedBuffers->size(); i++) {
+            const StreamBuffer &b = (*mNextCapturedBuffers)[i];
+            ALOGVV("Sensor capturing buffer %d: stream %d,"
+                    " %d x %d, format %x, stride %d, buf %p, img %p",
+                    i, b.streamId, b.width, b.height, b.format, b.stride,
+                    b.buffer, b.img);
+            switch(b.format) {
+                case HAL_PIXEL_FORMAT_RAW_SENSOR:
+                    captureRaw(b.img, gain, b.stride);
+                    break;
+                case HAL_PIXEL_FORMAT_RGB_888:
+                    captureRGB(b.img, gain, b.stride);
+                    break;
+                case HAL_PIXEL_FORMAT_RGBA_8888:
+                    captureRGBA(b.img, gain, b.stride);
+                    break;
+                case HAL_PIXEL_FORMAT_BLOB:
+                    // Add auxillary buffer of the right size
+                    // Assumes only one BLOB (JPEG) buffer in
+                    // mNextCapturedBuffers
+                    StreamBuffer bAux;
+                    bAux.streamId = 0;
+                    bAux.width = b.width;
+                    bAux.height = b.height;
+                    bAux.format = HAL_PIXEL_FORMAT_RGB_888;
+                    bAux.stride = b.width;
+                    bAux.buffer = NULL;
+                    // TODO: Reuse these
+                    bAux.img = new uint8_t[b.width * b.height * 3];
+                    mNextCapturedBuffers->push_back(bAux);
+                    break;
+                case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+                    captureNV21(b.img, gain, b.stride);
+                    break;
+                case HAL_PIXEL_FORMAT_YV12:
+                    // TODO:
+                    ALOGE("%s: Format %x is TODO", __FUNCTION__, b.format);
+                    break;
+                default:
+                    ALOGE("%s: Unknown format %x, no output", __FUNCTION__,
+                            b.format);
+                    break;
+            }
+        }
+    }
+
+    ALOGVV("Sensor vertical blanking interval");
+    nsecs_t workDoneRealTime = systemTime();
+    const nsecs_t timeAccuracy = 2e6; // 2 ms of imprecision is ok
+    if (workDoneRealTime < frameEndRealTime - timeAccuracy) {
+        timespec t;
+        t.tv_sec = (frameEndRealTime - workDoneRealTime)  / 1000000000L;
+        t.tv_nsec = (frameEndRealTime - workDoneRealTime) % 1000000000L;
+
+        int ret;
+        do {
+            ret = nanosleep(&t, &t);
+        } while (ret != 0);
+    }
+    nsecs_t endRealTime = systemTime();
+    ALOGVV("Frame cycle took %d ms, target %d ms",
+            (int)((endRealTime - startRealTime)/1000000),
+            (int)(frameDuration / 1000000));
+    return true;
+};
+
+void Sensor::captureRaw(uint8_t *img, uint32_t gain, uint32_t stride) {
+    float totalGain = gain/100.0 * kBaseGainFactor;
+    float noiseVarGain =  totalGain * totalGain;
+    float readNoiseVar = kReadNoiseVarBeforeGain * noiseVarGain
+            + kReadNoiseVarAfterGain;
+
+    int bayerSelect[4] = {Scene::R, Scene::Gr, Scene::Gb, Scene::B}; // RGGB
+    mScene.setReadoutPixel(0,0);
+    for (unsigned int y = 0; y < kResolution[1]; y++ ) {
+        int *bayerRow = bayerSelect + (y & 0x1) * 2;
+        uint16_t *px = (uint16_t*)img + y * stride;
+        for (unsigned int x = 0; x < kResolution[0]; x++) {
+            uint32_t electronCount;
+            electronCount = mScene.getPixelElectrons()[bayerRow[x & 0x1]];
+
+            // TODO: Better pixel saturation curve?
+            electronCount = (electronCount < kSaturationElectrons) ?
+                    electronCount : kSaturationElectrons;
+
+            // TODO: Better A/D saturation curve?
+            uint16_t rawCount = electronCount * totalGain;
+            rawCount = (rawCount < kMaxRawValue) ? rawCount : kMaxRawValue;
+
+            // Calculate noise value
+            // TODO: Use more-correct Gaussian instead of uniform noise
+            float photonNoiseVar = electronCount * noiseVarGain;
+            float noiseStddev = sqrtf_approx(readNoiseVar + photonNoiseVar);
+            // Scaled to roughly match gaussian/uniform noise stddev
+            float noiseSample = std::rand() * (2.5 / (1.0 + RAND_MAX)) - 1.25;
+
+            rawCount += kBlackLevel;
+            rawCount += noiseStddev * noiseSample;
+
+            *px++ = rawCount;
+        }
+        // TODO: Handle this better
+        //simulatedTime += kRowReadoutTime;
+    }
+    ALOGVV("Raw sensor image captured");
+}
+
+void Sensor::captureRGBA(uint8_t *img, uint32_t gain, uint32_t stride) {
+    float totalGain = gain/100.0 * kBaseGainFactor;
+    // In fixed-point math, calculate total scaling from electrons to 8bpp
+    int scale64x = 64 * totalGain * 255 / kMaxRawValue;
+    uint32_t inc = kResolution[0] / stride;
+
+    for (unsigned int y = 0, outY = 0; y < kResolution[1]; y+=inc, outY++ ) {
+        uint8_t *px = img + outY * stride * 4;
+        mScene.setReadoutPixel(0, y);
+        for (unsigned int x = 0; x < kResolution[0]; x+=inc) {
+            uint32_t rCount, gCount, bCount;
+            // TODO: Perfect demosaicing is a cheat
+            const uint32_t *pixel = mScene.getPixelElectrons();
+            rCount = pixel[Scene::R]  * scale64x;
+            gCount = pixel[Scene::Gr] * scale64x;
+            bCount = pixel[Scene::B]  * scale64x;
+
+            *px++ = rCount < 255*64 ? rCount / 64 : 255;
+            *px++ = gCount < 255*64 ? gCount / 64 : 255;
+            *px++ = bCount < 255*64 ? bCount / 64 : 255;
+            *px++ = 255;
+            for (unsigned int j = 1; j < inc; j++)
+                mScene.getPixelElectrons();
+        }
+        // TODO: Handle this better
+        //simulatedTime += kRowReadoutTime;
+    }
+    ALOGVV("RGBA sensor image captured");
+}
+
+void Sensor::captureRGB(uint8_t *img, uint32_t gain, uint32_t stride) {
+    float totalGain = gain/100.0 * kBaseGainFactor;
+    // In fixed-point math, calculate total scaling from electrons to 8bpp
+    int scale64x = 64 * totalGain * 255 / kMaxRawValue;
+    uint32_t inc = kResolution[0] / stride;
+
+    for (unsigned int y = 0, outY = 0; y < kResolution[1]; y += inc, outY++ ) {
+        mScene.setReadoutPixel(0, y);
+        uint8_t *px = img + outY * stride * 3;
+        for (unsigned int x = 0; x < kResolution[0]; x += inc) {
+            uint32_t rCount, gCount, bCount;
+            // TODO: Perfect demosaicing is a cheat
+            const uint32_t *pixel = mScene.getPixelElectrons();
+            rCount = pixel[Scene::R]  * scale64x;
+            gCount = pixel[Scene::Gr] * scale64x;
+            bCount = pixel[Scene::B]  * scale64x;
+
+            *px++ = rCount < 255*64 ? rCount / 64 : 255;
+            *px++ = gCount < 255*64 ? gCount / 64 : 255;
+            *px++ = bCount < 255*64 ? bCount / 64 : 255;
+            for (unsigned int j = 1; j < inc; j++)
+                mScene.getPixelElectrons();
+        }
+        // TODO: Handle this better
+        //simulatedTime += kRowReadoutTime;
+    }
+    ALOGVV("RGB sensor image captured");
+}
+
+void Sensor::captureNV21(uint8_t *img, uint32_t gain, uint32_t stride) {
+    float totalGain = gain/100.0 * kBaseGainFactor;
+    // In fixed-point math, calculate total scaling from electrons to 8bpp
+    int scale64x = 64 * totalGain * 255 / kMaxRawValue;
+
+    // TODO: Make full-color
+    uint32_t inc = kResolution[0] / stride;
+    uint32_t outH = kResolution[1] / inc;
+    for (unsigned int y = 0, outY = 0, outUV = outH;
+         y < kResolution[1]; y+=inc, outY++, outUV ) {
+        uint8_t *pxY = img + outY * stride;
+        mScene.setReadoutPixel(0,y);
+        for (unsigned int x = 0; x < kResolution[0]; x+=inc) {
+            uint32_t rCount, gCount, bCount;
+            // TODO: Perfect demosaicing is a cheat
+            const uint32_t *pixel = mScene.getPixelElectrons();
+            rCount = pixel[Scene::R]  * scale64x;
+            gCount = pixel[Scene::Gr] * scale64x;
+            bCount = pixel[Scene::B]  * scale64x;
+            uint32_t avg = (rCount + gCount + bCount) / 3;
+            *pxY++ = avg < 255*64 ? avg / 64 : 255;
+            for (unsigned int j = 1; j < inc; j++)
+                mScene.getPixelElectrons();
+        }
+    }
+    for (unsigned int y = 0, outY = outH; y < kResolution[1]/2; y+=inc, outY++) {
+        uint8_t *px = img + outY * stride;
+        for (unsigned int x = 0; x < kResolution[0]; x+=inc) {
+            // UV to neutral
+            *px++ = 128;
+            *px++ = 128;
+        }
+    }
+    ALOGVV("NV21 sensor image captured");
+}
+
+} // namespace android
diff --git a/camera/fake-pipeline2/Sensor.h b/camera/fake-pipeline2/Sensor.h
new file mode 100644
index 0000000..ce7b4ad
--- /dev/null
+++ b/camera/fake-pipeline2/Sensor.h
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 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.
+ */
+
+/**
+ * This class is a simple simulation of a typical CMOS cellphone imager chip,
+ * which outputs 12-bit Bayer-mosaic raw images.
+ *
+ * The sensor is abstracted as operating as a pipeline 3 stages deep;
+ * conceptually, each frame to be captured goes through these three stages. The
+ * processing step for the sensor is marked off by vertical sync signals, which
+ * indicate the start of readout of the oldest frame. The interval between
+ * processing steps depends on the frame duration of the frame currently being
+ * captured. The stages are 1) configure, 2) capture, and 3) readout. During
+ * configuration, the sensor's registers for settings such as exposure time,
+ * frame duration, and gain are set for the next frame to be captured. In stage
+ * 2, the image data for the frame is actually captured by the sensor. Finally,
+ * in stage 3, the just-captured data is read out and sent to the rest of the
+ * system.
+ *
+ * The sensor is assumed to be rolling-shutter, so low-numbered rows of the
+ * sensor are exposed earlier in time than larger-numbered rows, with the time
+ * offset between each row being equal to the row readout time.
+ *
+ * The characteristics of this sensor don't correspond to any actual sensor,
+ * but are not far off typical sensors.
+ *
+ * Example timing diagram, with three frames:
+ *  Frame 0-1: Frame duration 50 ms, exposure time 20 ms.
+ *  Frame   2: Frame duration 75 ms, exposure time 65 ms.
+ * Legend:
+ *   C = update sensor registers for frame
+ *   v = row in reset (vertical blanking interval)
+ *   E = row capturing image data
+ *   R = row being read out
+ *   | = vertical sync signal
+ *time(ms)|   0          55        105       155            230     270
+ * Frame 0|   :configure : capture : readout :              :       :
+ *  Row # | ..|CCCC______|_________|_________|              :       :
+ *      0 |   :\          \vvvvvEEEER         \             :       :
+ *    500 |   : \          \vvvvvEEEER         \            :       :
+ *   1000 |   :  \          \vvvvvEEEER         \           :       :
+ *   1500 |   :   \          \vvvvvEEEER         \          :       :
+ *   2000 |   :    \__________\vvvvvEEEER_________\         :       :
+ * Frame 1|   :           configure  capture      readout   :       :
+ *  Row # |   :          |CCCC_____|_________|______________|       :
+ *      0 |   :          :\         \vvvvvEEEER              \      :
+ *    500 |   :          : \         \vvvvvEEEER              \     :
+ *   1000 |   :          :  \         \vvvvvEEEER              \    :
+ *   1500 |   :          :   \         \vvvvvEEEER              \   :
+ *   2000 |   :          :    \_________\vvvvvEEEER______________\  :
+ * Frame 2|   :          :          configure     capture    readout:
+ *  Row # |   :          :         |CCCC_____|______________|_______|...
+ *      0 |   :          :         :\         \vEEEEEEEEEEEEER       \
+ *    500 |   :          :         : \         \vEEEEEEEEEEEEER       \
+ *   1000 |   :          :         :  \         \vEEEEEEEEEEEEER       \
+ *   1500 |   :          :         :   \         \vEEEEEEEEEEEEER       \
+ *   2000 |   :          :         :    \_________\vEEEEEEEEEEEEER_______\
+ */
+
+#ifndef HW_EMULATOR_CAMERA2_SENSOR_H
+#define HW_EMULATOR_CAMERA2_SENSOR_H
+
+#include "utils/Thread.h"
+#include "utils/Mutex.h"
+#include "utils/Timers.h"
+
+#include "Scene.h"
+#include "Base.h"
+
+namespace android {
+
+class EmulatedFakeCamera2;
+
+class Sensor: private Thread, public virtual RefBase {
+  public:
+
+    Sensor(EmulatedFakeCamera2 *parent);
+    ~Sensor();
+
+    /*
+     * Power control
+     */
+
+    status_t startUp();
+    status_t shutDown();
+
+    /*
+     * Access to scene
+     */
+    Scene &getScene();
+
+    /*
+     * Controls that can be updated every frame
+     */
+
+    void setExposureTime(uint64_t ns);
+    void setFrameDuration(uint64_t ns);
+    void setSensitivity(uint32_t gain);
+    // Buffer must be at least stride*height*2 bytes in size
+    void setDestinationBuffers(Buffers *buffers);
+
+    /*
+     * Controls that cause reconfiguration delay
+     */
+
+    void setBinning(int horizontalFactor, int verticalFactor);
+
+    /*
+     * Synchronizing with sensor operation (vertical sync)
+     */
+
+    // Wait until the sensor outputs its next vertical sync signal, meaning it
+    // is starting readout of its latest frame of data. Returns true if vertical
+    // sync is signaled, false if the wait timed out.
+    bool waitForVSync(nsecs_t reltime);
+
+    // Wait until a new frame has been read out, and then return the time
+    // capture started.  May return immediately if a new frame has been pushed
+    // since the last wait for a new frame. Returns true if new frame is
+    // returned, false if timed out.
+    bool waitForNewFrame(nsecs_t reltime,
+            nsecs_t *captureTime);
+
+    /**
+     * Static sensor characteristics
+     */
+    static const unsigned int kResolution[2];
+
+    static const nsecs_t kExposureTimeRange[2];
+    static const nsecs_t kFrameDurationRange[2];
+    static const nsecs_t kMinVerticalBlank;
+
+    static const uint8_t kColorFilterArrangement;
+
+    // Output image data characteristics
+    static const uint32_t kMaxRawValue;
+    static const uint32_t kBlackLevel;
+    // Sensor sensitivity, approximate
+
+    static const float kSaturationVoltage;
+    static const uint32_t kSaturationElectrons;
+    static const float kVoltsPerLuxSecond;
+    static const float kElectronsPerLuxSecond;
+
+    static const float kBaseGainFactor;
+
+    static const float kReadNoiseStddevBeforeGain; // In electrons
+    static const float kReadNoiseStddevAfterGain;  // In raw digital units
+    static const float kReadNoiseVarBeforeGain;
+    static const float kReadNoiseVarAfterGain;
+
+    // While each row has to read out, reset, and then expose, the (reset +
+    // expose) sequence can be overlapped by other row readouts, so the final
+    // minimum frame duration is purely a function of row readout time, at least
+    // if there's a reasonable number of rows.
+    static const nsecs_t kRowReadoutTime;
+
+    static const uint32_t kAvailableSensitivities[5];
+    static const uint32_t kDefaultSensitivity;
+
+  private:
+    EmulatedFakeCamera2 *mParent;
+
+    Mutex mControlMutex; // Lock before accessing control parameters
+    // Start of control parameters
+    Condition mVSync;
+    bool      mGotVSync;
+    uint64_t  mExposureTime;
+    uint64_t  mFrameDuration;
+    uint32_t  mGainFactor;
+    Buffers  *mNextBuffers;
+
+    // End of control parameters
+
+    Mutex mReadoutMutex; // Lock before accessing readout variables
+    // Start of readout variables
+    Condition mReadoutAvailable;
+    Condition mReadoutComplete;
+    Buffers  *mCapturedBuffers;
+    nsecs_t   mCaptureTime;
+    // End of readout variables
+
+    // Time of sensor startup, used for simulation zero-time point
+    nsecs_t mStartupTime;
+
+    /**
+     * Inherited Thread virtual overrides, and members only used by the
+     * processing thread
+     */
+  private:
+    virtual status_t readyToRun();
+
+    virtual bool threadLoop();
+
+    nsecs_t mNextCaptureTime;
+    Buffers *mNextCapturedBuffers;
+
+    Scene mScene;
+
+    void captureRaw(uint8_t *img, uint32_t gain, uint32_t stride);
+    void captureRGBA(uint8_t *img, uint32_t gain, uint32_t stride);
+    void captureRGB(uint8_t *img, uint32_t gain, uint32_t stride);
+    void captureNV21(uint8_t *img, uint32_t gain, uint32_t stride);
+};
+
+}
+
+#endif // HW_EMULATOR_CAMERA2_SENSOR_H
diff --git a/camera/media_codecs.xml b/camera/media_codecs.xml
new file mode 100644
index 0000000..c1af21a
--- /dev/null
+++ b/camera/media_codecs.xml
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!-- Copyright (C) 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.
+-->
+
+<!--
+<!DOCTYPE MediaCodecs [
+<!ELEMENT MediaCodecs (Decoders,Encoders)>
+<!ELEMENT Decoders (MediaCodec*)>
+<!ELEMENT Encoders (MediaCodec*)>
+<!ELEMENT MediaCodec (Type*,Quirk*)>
+<!ATTLIST MediaCodec name CDATA #REQUIRED>
+<!ATTLIST MediaCodec type CDATA>
+<!ELEMENT Type EMPTY>
+<!ATTLIST Type name CDATA #REQUIRED>
+<!ELEMENT Quirk EMPTY>
+<!ATTLIST Quirk name CDATA #REQUIRED>
+]>
+
+There's a simple and a complex syntax to declare the availability of a
+media codec:
+
+A codec that properly follows the OpenMax spec and therefore doesn't have any
+quirks and that only supports a single content type can be declared like so:
+
+    <MediaCodec name="OMX.foo.bar" type="something/interesting" />
+
+If a codec has quirks OR supports multiple content types, the following syntax
+can be used:
+
+    <MediaCodec name="OMX.foo.bar" >
+        <Type name="something/interesting" />
+        <Type name="something/else" />
+        ...
+        <Quirk name="requires-allocate-on-input-ports" />
+        <Quirk name="requires-allocate-on-output-ports" />
+        <Quirk name="output-buffers-are-unreadable" />
+    </MediaCodec>
+
+Only the three quirks included above are recognized at this point:
+
+"requires-allocate-on-input-ports"
+    must be advertised if the component does not properly support specification
+    of input buffers using the OMX_UseBuffer(...) API but instead requires
+    OMX_AllocateBuffer to be used.
+
+"requires-allocate-on-output-ports"
+    must be advertised if the component does not properly support specification
+    of output buffers using the OMX_UseBuffer(...) API but instead requires
+    OMX_AllocateBuffer to be used.
+
+"output-buffers-are-unreadable"
+    must be advertised if the emitted output buffers of a decoder component
+    are not readable, i.e. use a custom format even though abusing one of
+    the official OMX colorspace constants.
+    Clients of such decoders will not be able to access the decoded data,
+    naturally making the component much less useful. The only use for
+    a component with this quirk is to render the output to the screen.
+    Audio decoders MUST NOT advertise this quirk.
+    Video decoders that advertise this quirk must be accompanied by a
+    corresponding color space converter for thumbnail extraction,
+    matching surfaceflinger support that can render the custom format to
+    a texture and possibly other code, so just DON'T USE THIS QUIRK.
+
+-->
+
+<MediaCodecs>
+    <Decoders>
+        <MediaCodec name="OMX.google.mp3.decoder" type="audio/mpeg" />
+        <MediaCodec name="OMX.google.amrnb.decoder" type="audio/3gpp" />
+        <MediaCodec name="OMX.google.amrwb.decoder" type="audio/amr-wb" />
+        <MediaCodec name="OMX.google.aac.decoder" type="audio/mp4a-latm" />
+        <MediaCodec name="OMX.google.g711.alaw.decoder" type="audio/g711-alaw" />
+        <MediaCodec name="OMX.google.g711.mlaw.decoder" type="audio/g711-mlaw" />
+        <MediaCodec name="OMX.google.vorbis.decoder" type="audio/vorbis" />
+        <MediaCodec name="OMX.google.gsm.decoder" type="audio/gsm" />
+
+        <MediaCodec name="OMX.google.mpeg4.decoder" type="video/mp4v-es" />
+        <MediaCodec name="OMX.google.h263.decoder" type="video/3gpp" />
+        <MediaCodec name="OMX.google.h264.decoder" type="video/avc" />
+        <MediaCodec name="OMX.google.vpx.decoder" type="video/x-vnd.on2.vp8" />
+    </Decoders>
+
+    <Encoders>
+        <MediaCodec name="OMX.google.aac.encoder" type="audio/mp4a-latm" />
+        <MediaCodec name="OMX.google.amrnb.encoder" type="audio/3gpp" />
+        <MediaCodec name="OMX.google.amrwb.encoder" type="audio/amr-wb" />
+        <MediaCodec name="OMX.google.h263.encoder" type="video/3gpp" />
+        <MediaCodec name="OMX.google.h264.encoder" type="video/avc" />
+        <MediaCodec name="OMX.google.mpeg4.encoder" type="video/mp4v-es" />
+        <MediaCodec name="OMX.google.flac.encoder" type="audio/flac" />
+        <MediaCodec name="OMX.google.vpx.encoder" type="video/x-vnd.on2.vp8" />
+    </Encoders>
+</MediaCodecs>
diff --git a/camera/media_profiles.xml b/camera/media_profiles.xml
new file mode 100644
index 0000000..42ceb8d
--- /dev/null
+++ b/camera/media_profiles.xml
@@ -0,0 +1,414 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 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.
+-->
+<!DOCTYPE MediaSettings [
+<!ELEMENT MediaSettings (CamcorderProfiles,
+                         EncoderOutputFileFormat+,
+                         VideoEncoderCap+,
+                         AudioEncoderCap+,
+                         VideoDecoderCap,
+                         AudioDecoderCap)>
+<!ELEMENT CamcorderProfiles (EncoderProfile+, ImageEncoding+, ImageDecoding, Camera)>
+<!ELEMENT EncoderProfile (Video, Audio)>
+<!ATTLIST EncoderProfile quality (high|low) #REQUIRED>
+<!ATTLIST EncoderProfile fileFormat (mp4|3gp) #REQUIRED>
+<!ATTLIST EncoderProfile duration (30|60) #REQUIRED>
+<!ATTLIST EncoderProfile cameraId (0|1) #REQUIRED>
+<!ELEMENT Video EMPTY>
+<!ATTLIST Video codec (h264|h263|m4v) #REQUIRED>
+<!ATTLIST Video bitRate CDATA #REQUIRED>
+<!ATTLIST Video width CDATA #REQUIRED>
+<!ATTLIST Video height CDATA #REQUIRED>
+<!ATTLIST Video frameRate CDATA #REQUIRED>
+<!ELEMENT Audio EMPTY>
+<!ATTLIST Audio codec (amrnb|amrwb|aac) #REQUIRED>
+<!ATTLIST Audio bitRate CDATA #REQUIRED>
+<!ATTLIST Audio sampleRate CDATA #REQUIRED>
+<!ATTLIST Audio channels (1|2) #REQUIRED>
+<!ELEMENT ImageEncoding EMPTY>
+<!ATTLIST ImageEncoding quality (90|80|70|60|50|40) #REQUIRED>
+<!ELEMENT ImageDecoding EMPTY>
+<!ATTLIST ImageDecoding memCap CDATA #REQUIRED>
+<!ELEMENT Camera EMPTY>
+<!ELEMENT EncoderOutputFileFormat EMPTY>
+<!ATTLIST EncoderOutputFileFormat name (mp4|3gp) #REQUIRED>
+<!ELEMENT VideoEncoderCap EMPTY>
+<!ATTLIST VideoEncoderCap name (h264|h263|m4v|wmv) #REQUIRED>
+<!ATTLIST VideoEncoderCap enabled (true|false) #REQUIRED>
+<!ATTLIST VideoEncoderCap minBitRate CDATA #REQUIRED>
+<!ATTLIST VideoEncoderCap maxBitRate CDATA #REQUIRED>
+<!ATTLIST VideoEncoderCap minFrameWidth CDATA #REQUIRED>
+<!ATTLIST VideoEncoderCap maxFrameWidth CDATA #REQUIRED>
+<!ATTLIST VideoEncoderCap minFrameHeight CDATA #REQUIRED>
+<!ATTLIST VideoEncoderCap maxFrameHeight CDATA #REQUIRED>
+<!ATTLIST VideoEncoderCap minFrameRate CDATA #REQUIRED>
+<!ATTLIST VideoEncoderCap maxFrameRate CDATA #REQUIRED>
+<!ELEMENT AudioEncoderCap EMPTY>
+<!ATTLIST AudioEncoderCap name (amrnb|amrwb|aac|wma) #REQUIRED>
+<!ATTLIST AudioEncoderCap enabled (true|false) #REQUIRED>
+<!ATTLIST AudioEncoderCap minBitRate CDATA #REQUIRED>
+<!ATTLIST AudioEncoderCap maxBitRate CDATA #REQUIRED>
+<!ATTLIST AudioEncoderCap minSampleRate CDATA #REQUIRED>
+<!ATTLIST AudioEncoderCap maxSampleRate CDATA #REQUIRED>
+<!ATTLIST AudioEncoderCap minChannels (1|2) #REQUIRED>
+<!ATTLIST AudioEncoderCap maxChannels (1|2) #REQUIRED>
+<!ELEMENT VideoDecoderCap EMPTY>
+<!ATTLIST VideoDecoderCap name (wmv) #REQUIRED>
+<!ATTLIST VideoDecoderCap enabled (true|false) #REQUIRED>
+<!ELEMENT AudioDecoderCap EMPTY>
+<!ATTLIST AudioDecoderCap name (wma) #REQUIRED>
+<!ATTLIST AudioDecoderCap enabled (true|false) #REQUIRED>
+<!ELEMENT VideoEditorCap EMPTY>
+<!ATTLIST VideoEditorCap maxInputFrameWidth CDATA #REQUIRED>
+<!ATTLIST VideoEditorCap maxInputFrameHeight CDATA #REQUIRED>
+<!ATTLIST VideoEditorCap maxOutputFrameWidth CDATA #REQUIRED>
+<!ATTLIST VideoEditorCap maxOutputFrameHeight CDATA #REQUIRED>
+<!ATTLIST VideoEditorCap maxPrefetchYUVFrames CDATA #REQUIRED>
+<!ELEMENT ExportVideoProfile EMPTY>
+<!ATTLIST ExportVideoProfile name (h264|h263|m4v) #REQUIRED>
+<!ATTLIST ExportVideoProfile profile CDATA #REQUIRED>
+<!ATTLIST ExportVideoProfile level CDATA #REQUIRED>
+]>
+<!--
+     This file is used to declare the multimedia profiles and capabilities
+     on an android-powered device.
+-->
+<MediaSettings>
+    <!-- Each camcorder profile defines a set of predefined configuration parameters -->
+    <CamcorderProfiles cameraId="0">
+
+        <EncoderProfile quality="qvga" fileFormat="mp4" duration="60">
+            <Video codec="m4v"
+                   bitRate="128000"
+                   width="320"
+                   height="240"
+                   frameRate="15" />
+            <Audio codec="amrnb"
+                   bitRate="12200"
+                   sampleRate="8000"
+                   channels="1" />
+        </EncoderProfile>
+
+        <EncoderProfile quality="timelapseqcif" fileFormat="mp4" duration="30">
+            <Video codec="h264"
+                   bitRate="192000"
+                   width="176"
+                   height="144"
+                   frameRate="30" />
+            <!-- audio setting is ignored -->
+            <Audio codec="amrnb"
+                   bitRate="12200"
+                   sampleRate="8000"
+                   channels="1" />
+        </EncoderProfile>
+
+        <ImageEncoding quality="95" />
+        <ImageEncoding quality="80" />
+        <ImageEncoding quality="70" />
+        <ImageDecoding memCap="20000000" />
+
+    </CamcorderProfiles>
+
+    <CamcorderProfiles cameraId="1">
+
+        <EncoderProfile quality="qvga" fileFormat="mp4" duration="60">
+            <Video codec="m4v"
+                   bitRate="128000"
+                   width="320"
+                   height="240"
+                   frameRate="15" />
+            <Audio codec="amrnb"
+                   bitRate="12200"
+                   sampleRate="8000"
+                   channels="1" />
+        </EncoderProfile>
+
+        <EncoderProfile quality="timelapseqcif" fileFormat="mp4" duration="30">
+            <Video codec="h264"
+                   bitRate="192000"
+                   width="176"
+                   height="144"
+                   frameRate="30" />
+            <!-- audio setting is ignored -->
+            <Audio codec="amrnb"
+                   bitRate="12200"
+                   sampleRate="8000"
+                   channels="1" />
+        </EncoderProfile>
+
+        <ImageEncoding quality="95" />
+        <ImageEncoding quality="80" />
+        <ImageEncoding quality="70" />
+        <ImageDecoding memCap="20000000" />
+
+    </CamcorderProfiles>
+
+    <CamcorderProfiles cameraId="2">
+
+        <EncoderProfile quality="qvga" fileFormat="mp4" duration="60">
+            <Video codec="m4v"
+                   bitRate="128000"
+                   width="320"
+                   height="240"
+                   frameRate="15" />
+            <Audio codec="amrnb"
+                   bitRate="12200"
+                   sampleRate="8000"
+                   channels="1" />
+        </EncoderProfile>
+
+        <EncoderProfile quality="timelapseqcif" fileFormat="mp4" duration="30">
+            <Video codec="h264"
+                   bitRate="192000"
+                   width="176"
+                   height="144"
+                   frameRate="30" />
+            <!-- audio setting is ignored -->
+            <Audio codec="amrnb"
+                   bitRate="12200"
+                   sampleRate="8000"
+                   channels="1" />
+        </EncoderProfile>
+
+        <ImageEncoding quality="95" />
+        <ImageEncoding quality="80" />
+        <ImageEncoding quality="70" />
+        <ImageDecoding memCap="20000000" />
+
+    </CamcorderProfiles>
+
+    <CamcorderProfiles cameraId="3">
+
+        <EncoderProfile quality="qvga" fileFormat="mp4" duration="60">
+            <Video codec="m4v"
+                   bitRate="128000"
+                   width="320"
+                   height="240"
+                   frameRate="15" />
+            <Audio codec="amrnb"
+                   bitRate="12200"
+                   sampleRate="8000"
+                   channels="1" />
+        </EncoderProfile>
+
+        <EncoderProfile quality="timelapseqcif" fileFormat="mp4" duration="30">
+            <Video codec="h264"
+                   bitRate="192000"
+                   width="176"
+                   height="144"
+                   frameRate="30" />
+            <!-- audio setting is ignored -->
+            <Audio codec="amrnb"
+                   bitRate="12200"
+                   sampleRate="8000"
+                   channels="1" />
+        </EncoderProfile>
+
+        <ImageEncoding quality="95" />
+        <ImageEncoding quality="80" />
+        <ImageEncoding quality="70" />
+        <ImageDecoding memCap="20000000" />
+
+    </CamcorderProfiles>
+
+    <CamcorderProfiles cameraId="4">
+
+        <EncoderProfile quality="qvga" fileFormat="mp4" duration="60">
+            <Video codec="m4v"
+                   bitRate="128000"
+                   width="320"
+                   height="240"
+                   frameRate="15" />
+            <Audio codec="amrnb"
+                   bitRate="12200"
+                   sampleRate="8000"
+                   channels="1" />
+        </EncoderProfile>
+
+        <EncoderProfile quality="timelapseqcif" fileFormat="mp4" duration="30">
+            <Video codec="h264"
+                   bitRate="192000"
+                   width="176"
+                   height="144"
+                   frameRate="30" />
+            <!-- audio setting is ignored -->
+            <Audio codec="amrnb"
+                   bitRate="12200"
+                   sampleRate="8000"
+                   channels="1" />
+        </EncoderProfile>
+
+        <ImageEncoding quality="95" />
+        <ImageEncoding quality="80" />
+        <ImageEncoding quality="70" />
+        <ImageDecoding memCap="20000000" />
+
+    </CamcorderProfiles>
+
+    <CamcorderProfiles cameraId="5">
+
+        <EncoderProfile quality="qvga" fileFormat="mp4" duration="60">
+            <Video codec="m4v"
+                   bitRate="128000"
+                   width="320"
+                   height="240"
+                   frameRate="15" />
+            <Audio codec="amrnb"
+                   bitRate="12200"
+                   sampleRate="8000"
+                   channels="1" />
+        </EncoderProfile>
+
+        <EncoderProfile quality="timelapseqcif" fileFormat="mp4" duration="30">
+            <Video codec="h264"
+                   bitRate="192000"
+                   width="176"
+                   height="144"
+                   frameRate="30" />
+            <!-- audio setting is ignored -->
+            <Audio codec="amrnb"
+                   bitRate="12200"
+                   sampleRate="8000"
+                   channels="1" />
+        </EncoderProfile>
+
+        <ImageEncoding quality="95" />
+        <ImageEncoding quality="80" />
+        <ImageEncoding quality="70" />
+        <ImageDecoding memCap="20000000" />
+
+    </CamcorderProfiles>
+
+    <CamcorderProfiles cameraId="6">
+
+        <EncoderProfile quality="qvga" fileFormat="mp4" duration="60">
+            <Video codec="m4v"
+                   bitRate="128000"
+                   width="320"
+                   height="240"
+                   frameRate="15" />
+            <Audio codec="amrnb"
+                   bitRate="12200"
+                   sampleRate="8000"
+                   channels="1" />
+        </EncoderProfile>
+
+        <EncoderProfile quality="timelapseqcif" fileFormat="mp4" duration="30">
+            <Video codec="h264"
+                   bitRate="192000"
+                   width="176"
+                   height="144"
+                   frameRate="30" />
+            <!-- audio setting is ignored -->
+            <Audio codec="amrnb"
+                   bitRate="12200"
+                   sampleRate="8000"
+                   channels="1" />
+        </EncoderProfile>
+
+        <ImageEncoding quality="95" />
+        <ImageEncoding quality="80" />
+        <ImageEncoding quality="70" />
+        <ImageDecoding memCap="20000000" />
+
+    </CamcorderProfiles>
+
+    <EncoderOutputFileFormat name="3gp" />
+    <EncoderOutputFileFormat name="mp4" />
+
+    <!--
+         If a codec is not enabled, it is invisible to the applications
+         In other words, the applications won't be able to use the codec
+         or query the capabilities of the codec at all if it is disabled
+    -->
+    <VideoEncoderCap name="h264" enabled="true"
+        minBitRate="64000" maxBitRate="192000"
+        minFrameWidth="176" maxFrameWidth="320"
+        minFrameHeight="144" maxFrameHeight="240"
+        minFrameRate="15" maxFrameRate="30" />
+
+    <VideoEncoderCap name="h263" enabled="true"
+        minBitRate="64000" maxBitRate="192000"
+        minFrameWidth="176" maxFrameWidth="320"
+        minFrameHeight="144" maxFrameHeight="240"
+        minFrameRate="15" maxFrameRate="30" />
+
+    <VideoEncoderCap name="m4v" enabled="true"
+        minBitRate="64000" maxBitRate="192000"
+        minFrameWidth="176" maxFrameWidth="320"
+        minFrameHeight="144" maxFrameHeight="240"
+        minFrameRate="15" maxFrameRate="30" />
+
+    <AudioEncoderCap name="aac" enabled="true"
+        minBitRate="8000" maxBitRate="96000"
+        minSampleRate="8000" maxSampleRate="48000"
+        minChannels="1" maxChannels="1" />
+
+    <AudioEncoderCap name="amrwb" enabled="true"
+        minBitRate="6600" maxBitRate="23050"
+        minSampleRate="16000" maxSampleRate="16000"
+        minChannels="1" maxChannels="1" />
+
+    <AudioEncoderCap name="amrnb" enabled="true"
+        minBitRate="5525" maxBitRate="12200"
+        minSampleRate="8000" maxSampleRate="8000"
+        minChannels="1" maxChannels="1" />
+
+    <!--
+        FIXME:
+        We do not check decoder capabilities at present
+        At present, we only check whether windows media is visible
+        for TEST applications. For other applications, we do
+        not perform any checks at all.
+    -->
+    <VideoDecoderCap name="wmv" enabled="false"/>
+    <AudioDecoderCap name="wma" enabled="false"/>
+
+    <!--
+        The VideoEditor Capability configuration:
+        - maxInputFrameWidth: maximum video width of imported video clip.
+        - maxInputFrameHeight: maximum video height of imported video clip.
+        - maxOutputFrameWidth: maximum video width of exported video clip.
+        - maxOutputFrameHeight: maximum video height of exported video clip.
+        - maxPrefetchYUVFrames: maximum prefetch YUV frames for encoder,
+        used to limit the amount of memory for prefetched YUV frames.
+        For this platform, it allows maximum ~1MB(~0.1MB per QVGA frame x 10
+        frames) memory.
+    -->
+
+    <VideoEditorCap  maxInputFrameWidth="320"
+        maxInputFrameHeight="240" maxOutputFrameWidth="320"
+        maxOutputFrameHeight="240" maxPrefetchYUVFrames="10" />
+    <!--
+        The VideoEditor Export codec profile and level values
+        correspond to the values in OMX_Video.h.
+        E.g. for h264, profile value 1 means OMX_VIDEO_AVCProfileBaseline
+        and  level 4096 means OMX_VIDEO_AVCLevel41.
+        Please note that the values are in decimal.
+        These values are for video encoder.
+    -->
+    <!--
+      Codec = h.264, Baseline profile, level 4.1
+    -->
+    <ExportVideoProfile name="h264" profile= "1" level="512"/>
+    <!--
+      Codec = h.263, Baseline profile, level 0
+    -->
+    <ExportVideoProfile name="h263" profile= "1" level="1"/>
+    <!--
+      Codec = mpeg4, Simple profile, level 3
+    -->
+    <ExportVideoProfile name="m4v" profile= "1" level="16"/>
+</MediaSettings>
diff --git a/gps/Android.mk b/gps/Android.mk
new file mode 100644
index 0000000..6840f84
--- /dev/null
+++ b/gps/Android.mk
@@ -0,0 +1,36 @@
+# Copyright (C) 2010 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.
+
+
+# We're moving the emulator-specific platform libs to
+# development.git/tools/emulator/. The following test is to ensure
+# smooth builds even if the tree contains both versions.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+# HAL module implemenation stored in
+# hw/<GPS_HARDWARE_MODULE_ID>.<ro.hardware>.so
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
+LOCAL_CFLAGS += -DQEMU_HARDWARE
+LOCAL_SHARED_LIBRARIES := liblog libcutils libhardware
+LOCAL_SRC_FILES := gps_qemu.c
+ifeq ($(TARGET_PRODUCT),vbox_x86)
+LOCAL_MODULE := gps.vbox_x86
+else
+LOCAL_MODULE := gps.goldfish
+endif
+include $(BUILD_SHARED_LIBRARY)
diff --git a/gps/gps_qemu.c b/gps/gps_qemu.c
new file mode 100644
index 0000000..8f3d6e9
--- /dev/null
+++ b/gps/gps_qemu.c
@@ -0,0 +1,955 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+/* this implements a GPS hardware library for the Android emulator.
+ * the following code should be built as a shared library that will be
+ * placed into /system/lib/hw/gps.goldfish.so
+ *
+ * it will be loaded by the code in hardware/libhardware/hardware.c
+ * which is itself called from android_location_GpsLocationProvider.cpp
+ */
+
+
+#include <errno.h>
+#include <pthread.h>
+#include <fcntl.h>
+#include <sys/epoll.h>
+#include <math.h>
+#include <time.h>
+
+#define  LOG_TAG  "gps_qemu"
+#include <cutils/log.h>
+#include <cutils/sockets.h>
+#include <hardware/gps.h>
+#include <hardware/qemud.h>
+
+/* the name of the qemud-controlled socket */
+#define  QEMU_CHANNEL_NAME  "gps"
+
+#define  GPS_DEBUG  0
+
+#if GPS_DEBUG
+#  define  D(...)   ALOGD(__VA_ARGS__)
+#else
+#  define  D(...)   ((void)0)
+#endif
+
+/*****************************************************************/
+/*****************************************************************/
+/*****                                                       *****/
+/*****       N M E A   T O K E N I Z E R                     *****/
+/*****                                                       *****/
+/*****************************************************************/
+/*****************************************************************/
+
+typedef struct {
+    const char*  p;
+    const char*  end;
+} Token;
+
+#define  MAX_NMEA_TOKENS  16
+
+typedef struct {
+    int     count;
+    Token   tokens[ MAX_NMEA_TOKENS ];
+} NmeaTokenizer;
+
+static int
+nmea_tokenizer_init( NmeaTokenizer*  t, const char*  p, const char*  end )
+{
+    int    count = 0;
+    char*  q;
+
+    // the initial '$' is optional
+    if (p < end && p[0] == '$')
+        p += 1;
+
+    // remove trailing newline
+    if (end > p && end[-1] == '\n') {
+        end -= 1;
+        if (end > p && end[-1] == '\r')
+            end -= 1;
+    }
+
+    // get rid of checksum at the end of the sentecne
+    if (end >= p+3 && end[-3] == '*') {
+        end -= 3;
+    }
+
+    while (p < end) {
+        const char*  q = p;
+
+        q = memchr(p, ',', end-p);
+        if (q == NULL)
+            q = end;
+
+        if (q > p) {
+            if (count < MAX_NMEA_TOKENS) {
+                t->tokens[count].p   = p;
+                t->tokens[count].end = q;
+                count += 1;
+            }
+        }
+        if (q < end)
+            q += 1;
+
+        p = q;
+    }
+
+    t->count = count;
+    return count;
+}
+
+static Token
+nmea_tokenizer_get( NmeaTokenizer*  t, int  index )
+{
+    Token  tok;
+    static const char*  dummy = "";
+
+    if (index < 0 || index >= t->count) {
+        tok.p = tok.end = dummy;
+    } else
+        tok = t->tokens[index];
+
+    return tok;
+}
+
+
+static int
+str2int( const char*  p, const char*  end )
+{
+    int   result = 0;
+    int   len    = end - p;
+
+    for ( ; len > 0; len--, p++ )
+    {
+        int  c;
+
+        if (p >= end)
+            goto Fail;
+
+        c = *p - '0';
+        if ((unsigned)c >= 10)
+            goto Fail;
+
+        result = result*10 + c;
+    }
+    return  result;
+
+Fail:
+    return -1;
+}
+
+static double
+str2float( const char*  p, const char*  end )
+{
+    int   result = 0;
+    int   len    = end - p;
+    char  temp[16];
+
+    if (len >= (int)sizeof(temp))
+        return 0.;
+
+    memcpy( temp, p, len );
+    temp[len] = 0;
+    return strtod( temp, NULL );
+}
+
+/*****************************************************************/
+/*****************************************************************/
+/*****                                                       *****/
+/*****       N M E A   P A R S E R                           *****/
+/*****                                                       *****/
+/*****************************************************************/
+/*****************************************************************/
+
+#define  NMEA_MAX_SIZE  83
+
+typedef struct {
+    int     pos;
+    int     overflow;
+    int     utc_year;
+    int     utc_mon;
+    int     utc_day;
+    int     utc_diff;
+    GpsLocation  fix;
+    gps_location_callback  callback;
+    char    in[ NMEA_MAX_SIZE+1 ];
+} NmeaReader;
+
+
+static void
+nmea_reader_update_utc_diff( NmeaReader*  r )
+{
+    time_t         now = time(NULL);
+    struct tm      tm_local;
+    struct tm      tm_utc;
+    long           time_local, time_utc;
+
+    gmtime_r( &now, &tm_utc );
+    localtime_r( &now, &tm_local );
+
+    time_local = tm_local.tm_sec +
+                 60*(tm_local.tm_min +
+                 60*(tm_local.tm_hour +
+                 24*(tm_local.tm_yday +
+                 365*tm_local.tm_year)));
+
+    time_utc = tm_utc.tm_sec +
+               60*(tm_utc.tm_min +
+               60*(tm_utc.tm_hour +
+               24*(tm_utc.tm_yday +
+               365*tm_utc.tm_year)));
+
+    r->utc_diff = time_utc - time_local;
+}
+
+
+static void
+nmea_reader_init( NmeaReader*  r )
+{
+    memset( r, 0, sizeof(*r) );
+
+    r->pos      = 0;
+    r->overflow = 0;
+    r->utc_year = -1;
+    r->utc_mon  = -1;
+    r->utc_day  = -1;
+    r->callback = NULL;
+    r->fix.size = sizeof(r->fix);
+
+    nmea_reader_update_utc_diff( r );
+}
+
+
+static void
+nmea_reader_set_callback( NmeaReader*  r, gps_location_callback  cb )
+{
+    r->callback = cb;
+    if (cb != NULL && r->fix.flags != 0) {
+        D("%s: sending latest fix to new callback", __FUNCTION__);
+        r->callback( &r->fix );
+        r->fix.flags = 0;
+    }
+}
+
+
+static int
+nmea_reader_update_time( NmeaReader*  r, Token  tok )
+{
+    int        hour, minute;
+    double     seconds;
+    struct tm  tm;
+    time_t     fix_time;
+
+    if (tok.p + 6 > tok.end)
+        return -1;
+
+    if (r->utc_year < 0) {
+        // no date yet, get current one
+        time_t  now = time(NULL);
+        gmtime_r( &now, &tm );
+        r->utc_year = tm.tm_year + 1900;
+        r->utc_mon  = tm.tm_mon + 1;
+        r->utc_day  = tm.tm_mday;
+    }
+
+    hour    = str2int(tok.p,   tok.p+2);
+    minute  = str2int(tok.p+2, tok.p+4);
+    seconds = str2float(tok.p+4, tok.end);
+
+    tm.tm_hour  = hour;
+    tm.tm_min   = minute;
+    tm.tm_sec   = (int) seconds;
+    tm.tm_year  = r->utc_year - 1900;
+    tm.tm_mon   = r->utc_mon - 1;
+    tm.tm_mday  = r->utc_day;
+    tm.tm_isdst = -1;
+
+    fix_time = mktime( &tm ) + r->utc_diff;
+    r->fix.timestamp = (long long)fix_time * 1000;
+    return 0;
+}
+
+static int
+nmea_reader_update_date( NmeaReader*  r, Token  date, Token  time )
+{
+    Token  tok = date;
+    int    day, mon, year;
+
+    if (tok.p + 6 != tok.end) {
+        D("date not properly formatted: '%.*s'", tok.end-tok.p, tok.p);
+        return -1;
+    }
+    day  = str2int(tok.p, tok.p+2);
+    mon  = str2int(tok.p+2, tok.p+4);
+    year = str2int(tok.p+4, tok.p+6) + 2000;
+
+    if ((day|mon|year) < 0) {
+        D("date not properly formatted: '%.*s'", tok.end-tok.p, tok.p);
+        return -1;
+    }
+
+    r->utc_year  = year;
+    r->utc_mon   = mon;
+    r->utc_day   = day;
+
+    return nmea_reader_update_time( r, time );
+}
+
+
+static double
+convert_from_hhmm( Token  tok )
+{
+    double  val     = str2float(tok.p, tok.end);
+    int     degrees = (int)(floor(val) / 100);
+    double  minutes = val - degrees*100.;
+    double  dcoord  = degrees + minutes / 60.0;
+    return dcoord;
+}
+
+
+static int
+nmea_reader_update_latlong( NmeaReader*  r,
+                            Token        latitude,
+                            char         latitudeHemi,
+                            Token        longitude,
+                            char         longitudeHemi )
+{
+    double   lat, lon;
+    Token    tok;
+
+    tok = latitude;
+    if (tok.p + 6 > tok.end) {
+        D("latitude is too short: '%.*s'", tok.end-tok.p, tok.p);
+        return -1;
+    }
+    lat = convert_from_hhmm(tok);
+    if (latitudeHemi == 'S')
+        lat = -lat;
+
+    tok = longitude;
+    if (tok.p + 6 > tok.end) {
+        D("longitude is too short: '%.*s'", tok.end-tok.p, tok.p);
+        return -1;
+    }
+    lon = convert_from_hhmm(tok);
+    if (longitudeHemi == 'W')
+        lon = -lon;
+
+    r->fix.flags    |= GPS_LOCATION_HAS_LAT_LONG;
+    r->fix.latitude  = lat;
+    r->fix.longitude = lon;
+    return 0;
+}
+
+
+static int
+nmea_reader_update_altitude( NmeaReader*  r,
+                             Token        altitude,
+                             Token        units )
+{
+    double  alt;
+    Token   tok = altitude;
+
+    if (tok.p >= tok.end)
+        return -1;
+
+    r->fix.flags   |= GPS_LOCATION_HAS_ALTITUDE;
+    r->fix.altitude = str2float(tok.p, tok.end);
+    return 0;
+}
+
+
+static int
+nmea_reader_update_bearing( NmeaReader*  r,
+                            Token        bearing )
+{
+    double  alt;
+    Token   tok = bearing;
+
+    if (tok.p >= tok.end)
+        return -1;
+
+    r->fix.flags   |= GPS_LOCATION_HAS_BEARING;
+    r->fix.bearing  = str2float(tok.p, tok.end);
+    return 0;
+}
+
+
+static int
+nmea_reader_update_speed( NmeaReader*  r,
+                          Token        speed )
+{
+    double  alt;
+    Token   tok = speed;
+
+    if (tok.p >= tok.end)
+        return -1;
+
+    r->fix.flags   |= GPS_LOCATION_HAS_SPEED;
+    r->fix.speed    = str2float(tok.p, tok.end);
+    return 0;
+}
+
+static int
+nmea_reader_update_accuracy( NmeaReader*  r )
+{
+    // Always return 20m accuracy.
+    // Possibly parse it from the NMEA sentence in the future.
+    r->fix.flags    |= GPS_LOCATION_HAS_ACCURACY;
+    r->fix.accuracy = 20;
+    return 0;
+}
+
+
+static void
+nmea_reader_parse( NmeaReader*  r )
+{
+   /* we received a complete sentence, now parse it to generate
+    * a new GPS fix...
+    */
+    NmeaTokenizer  tzer[1];
+    Token          tok;
+
+    D("Received: '%.*s'", r->pos, r->in);
+    if (r->pos < 9) {
+        D("Too short. discarded.");
+        return;
+    }
+
+    nmea_tokenizer_init(tzer, r->in, r->in + r->pos);
+#if GPS_DEBUG
+    {
+        int  n;
+        D("Found %d tokens", tzer->count);
+        for (n = 0; n < tzer->count; n++) {
+            Token  tok = nmea_tokenizer_get(tzer,n);
+            D("%2d: '%.*s'", n, tok.end-tok.p, tok.p);
+        }
+    }
+#endif
+
+    tok = nmea_tokenizer_get(tzer, 0);
+    if (tok.p + 5 > tok.end) {
+        D("sentence id '%.*s' too short, ignored.", tok.end-tok.p, tok.p);
+        return;
+    }
+
+    // ignore first two characters.
+    tok.p += 2;
+    if ( !memcmp(tok.p, "GGA", 3) ) {
+        // GPS fix
+        Token  tok_time          = nmea_tokenizer_get(tzer,1);
+        Token  tok_latitude      = nmea_tokenizer_get(tzer,2);
+        Token  tok_latitudeHemi  = nmea_tokenizer_get(tzer,3);
+        Token  tok_longitude     = nmea_tokenizer_get(tzer,4);
+        Token  tok_longitudeHemi = nmea_tokenizer_get(tzer,5);
+        Token  tok_altitude      = nmea_tokenizer_get(tzer,9);
+        Token  tok_altitudeUnits = nmea_tokenizer_get(tzer,10);
+
+        nmea_reader_update_time(r, tok_time);
+        nmea_reader_update_latlong(r, tok_latitude,
+                                      tok_latitudeHemi.p[0],
+                                      tok_longitude,
+                                      tok_longitudeHemi.p[0]);
+        nmea_reader_update_altitude(r, tok_altitude, tok_altitudeUnits);
+
+    } else if ( !memcmp(tok.p, "GSA", 3) ) {
+        // do something ?
+    } else if ( !memcmp(tok.p, "RMC", 3) ) {
+        Token  tok_time          = nmea_tokenizer_get(tzer,1);
+        Token  tok_fixStatus     = nmea_tokenizer_get(tzer,2);
+        Token  tok_latitude      = nmea_tokenizer_get(tzer,3);
+        Token  tok_latitudeHemi  = nmea_tokenizer_get(tzer,4);
+        Token  tok_longitude     = nmea_tokenizer_get(tzer,5);
+        Token  tok_longitudeHemi = nmea_tokenizer_get(tzer,6);
+        Token  tok_speed         = nmea_tokenizer_get(tzer,7);
+        Token  tok_bearing       = nmea_tokenizer_get(tzer,8);
+        Token  tok_date          = nmea_tokenizer_get(tzer,9);
+
+        D("in RMC, fixStatus=%c", tok_fixStatus.p[0]);
+        if (tok_fixStatus.p[0] == 'A')
+        {
+            nmea_reader_update_date( r, tok_date, tok_time );
+
+            nmea_reader_update_latlong( r, tok_latitude,
+                                           tok_latitudeHemi.p[0],
+                                           tok_longitude,
+                                           tok_longitudeHemi.p[0] );
+
+            nmea_reader_update_bearing( r, tok_bearing );
+            nmea_reader_update_speed  ( r, tok_speed );
+        }
+    } else {
+        tok.p -= 2;
+        D("unknown sentence '%.*s", tok.end-tok.p, tok.p);
+    }
+
+    // Always update accuracy
+    nmea_reader_update_accuracy( r );
+
+    if (r->fix.flags != 0) {
+#if GPS_DEBUG
+        char   temp[256];
+        char*  p   = temp;
+        char*  end = p + sizeof(temp);
+        struct tm   utc;
+
+        p += snprintf( p, end-p, "sending fix" );
+        if (r->fix.flags & GPS_LOCATION_HAS_LAT_LONG) {
+            p += snprintf(p, end-p, " lat=%g lon=%g", r->fix.latitude, r->fix.longitude);
+        }
+        if (r->fix.flags & GPS_LOCATION_HAS_ALTITUDE) {
+            p += snprintf(p, end-p, " altitude=%g", r->fix.altitude);
+        }
+        if (r->fix.flags & GPS_LOCATION_HAS_SPEED) {
+            p += snprintf(p, end-p, " speed=%g", r->fix.speed);
+        }
+        if (r->fix.flags & GPS_LOCATION_HAS_BEARING) {
+            p += snprintf(p, end-p, " bearing=%g", r->fix.bearing);
+        }
+        if (r->fix.flags & GPS_LOCATION_HAS_ACCURACY) {
+            p += snprintf(p,end-p, " accuracy=%g", r->fix.accuracy);
+        }
+        gmtime_r( (time_t*) &r->fix.timestamp, &utc );
+        p += snprintf(p, end-p, " time=%s", asctime( &utc ) );
+        D(temp);
+#endif
+        if (r->callback) {
+            r->callback( &r->fix );
+            r->fix.flags = 0;
+        }
+        else {
+            D("no callback, keeping data until needed !");
+        }
+    }
+}
+
+
+static void
+nmea_reader_addc( NmeaReader*  r, int  c )
+{
+    if (r->overflow) {
+        r->overflow = (c != '\n');
+        return;
+    }
+
+    if (r->pos >= (int) sizeof(r->in)-1 ) {
+        r->overflow = 1;
+        r->pos      = 0;
+        return;
+    }
+
+    r->in[r->pos] = (char)c;
+    r->pos       += 1;
+
+    if (c == '\n') {
+        nmea_reader_parse( r );
+        r->pos = 0;
+    }
+}
+
+
+/*****************************************************************/
+/*****************************************************************/
+/*****                                                       *****/
+/*****       C O N N E C T I O N   S T A T E                 *****/
+/*****                                                       *****/
+/*****************************************************************/
+/*****************************************************************/
+
+/* commands sent to the gps thread */
+enum {
+    CMD_QUIT  = 0,
+    CMD_START = 1,
+    CMD_STOP  = 2
+};
+
+
+/* this is the state of our connection to the qemu_gpsd daemon */
+typedef struct {
+    int                     init;
+    int                     fd;
+    GpsCallbacks            callbacks;
+    pthread_t               thread;
+    int                     control[2];
+} GpsState;
+
+static GpsState  _gps_state[1];
+
+
+static void
+gps_state_done( GpsState*  s )
+{
+    // tell the thread to quit, and wait for it
+    char   cmd = CMD_QUIT;
+    void*  dummy;
+    write( s->control[0], &cmd, 1 );
+    pthread_join(s->thread, &dummy);
+
+    // close the control socket pair
+    close( s->control[0] ); s->control[0] = -1;
+    close( s->control[1] ); s->control[1] = -1;
+
+    // close connection to the QEMU GPS daemon
+    close( s->fd ); s->fd = -1;
+    s->init = 0;
+}
+
+
+static void
+gps_state_start( GpsState*  s )
+{
+    char  cmd = CMD_START;
+    int   ret;
+
+    do { ret=write( s->control[0], &cmd, 1 ); }
+    while (ret < 0 && errno == EINTR);
+
+    if (ret != 1)
+        D("%s: could not send CMD_START command: ret=%d: %s",
+          __FUNCTION__, ret, strerror(errno));
+}
+
+
+static void
+gps_state_stop( GpsState*  s )
+{
+    char  cmd = CMD_STOP;
+    int   ret;
+
+    do { ret=write( s->control[0], &cmd, 1 ); }
+    while (ret < 0 && errno == EINTR);
+
+    if (ret != 1)
+        D("%s: could not send CMD_STOP command: ret=%d: %s",
+          __FUNCTION__, ret, strerror(errno));
+}
+
+
+static int
+epoll_register( int  epoll_fd, int  fd )
+{
+    struct epoll_event  ev;
+    int                 ret, flags;
+
+    /* important: make the fd non-blocking */
+    flags = fcntl(fd, F_GETFL);
+    fcntl(fd, F_SETFL, flags | O_NONBLOCK);
+
+    ev.events  = EPOLLIN;
+    ev.data.fd = fd;
+    do {
+        ret = epoll_ctl( epoll_fd, EPOLL_CTL_ADD, fd, &ev );
+    } while (ret < 0 && errno == EINTR);
+    return ret;
+}
+
+
+static int
+epoll_deregister( int  epoll_fd, int  fd )
+{
+    int  ret;
+    do {
+        ret = epoll_ctl( epoll_fd, EPOLL_CTL_DEL, fd, NULL );
+    } while (ret < 0 && errno == EINTR);
+    return ret;
+}
+
+/* this is the main thread, it waits for commands from gps_state_start/stop and,
+ * when started, messages from the QEMU GPS daemon. these are simple NMEA sentences
+ * that must be parsed to be converted into GPS fixes sent to the framework
+ */
+static void
+gps_state_thread( void*  arg )
+{
+    GpsState*   state = (GpsState*) arg;
+    NmeaReader  reader[1];
+    int         epoll_fd   = epoll_create(2);
+    int         started    = 0;
+    int         gps_fd     = state->fd;
+    int         control_fd = state->control[1];
+
+    nmea_reader_init( reader );
+
+    // register control file descriptors for polling
+    epoll_register( epoll_fd, control_fd );
+    epoll_register( epoll_fd, gps_fd );
+
+    D("gps thread running");
+
+    // now loop
+    for (;;) {
+        struct epoll_event   events[2];
+        int                  ne, nevents;
+
+        nevents = epoll_wait( epoll_fd, events, 2, -1 );
+        if (nevents < 0) {
+            if (errno != EINTR)
+                ALOGE("epoll_wait() unexpected error: %s", strerror(errno));
+            continue;
+        }
+        D("gps thread received %d events", nevents);
+        for (ne = 0; ne < nevents; ne++) {
+            if ((events[ne].events & (EPOLLERR|EPOLLHUP)) != 0) {
+                ALOGE("EPOLLERR or EPOLLHUP after epoll_wait() !?");
+                return;
+            }
+            if ((events[ne].events & EPOLLIN) != 0) {
+                int  fd = events[ne].data.fd;
+
+                if (fd == control_fd)
+                {
+                    char  cmd = 255;
+                    int   ret;
+                    D("gps control fd event");
+                    do {
+                        ret = read( fd, &cmd, 1 );
+                    } while (ret < 0 && errno == EINTR);
+
+                    if (cmd == CMD_QUIT) {
+                        D("gps thread quitting on demand");
+                        return;
+                    }
+                    else if (cmd == CMD_START) {
+                        if (!started) {
+                            D("gps thread starting  location_cb=%p", state->callbacks.location_cb);
+                            started = 1;
+                            nmea_reader_set_callback( reader, state->callbacks.location_cb );
+                        }
+                    }
+                    else if (cmd == CMD_STOP) {
+                        if (started) {
+                            D("gps thread stopping");
+                            started = 0;
+                            nmea_reader_set_callback( reader, NULL );
+                        }
+                    }
+                }
+                else if (fd == gps_fd)
+                {
+                    char  buff[32];
+                    D("gps fd event");
+                    for (;;) {
+                        int  nn, ret;
+
+                        ret = read( fd, buff, sizeof(buff) );
+                        if (ret < 0) {
+                            if (errno == EINTR)
+                                continue;
+                            if (errno != EWOULDBLOCK)
+                                ALOGE("error while reading from gps daemon socket: %s:", strerror(errno));
+                            break;
+                        }
+                        D("received %d bytes: %.*s", ret, ret, buff);
+                        for (nn = 0; nn < ret; nn++)
+                            nmea_reader_addc( reader, buff[nn] );
+                    }
+                    D("gps fd event end");
+                }
+                else
+                {
+                    ALOGE("epoll_wait() returned unkown fd %d ?", fd);
+                }
+            }
+        }
+    }
+}
+
+
+static void
+gps_state_init( GpsState*  state, GpsCallbacks* callbacks )
+{
+    state->init       = 1;
+    state->control[0] = -1;
+    state->control[1] = -1;
+    state->fd         = -1;
+
+    state->fd = qemud_channel_open(QEMU_CHANNEL_NAME);
+
+    if (state->fd < 0) {
+        D("no gps emulation detected");
+        return;
+    }
+
+    D("gps emulation will read from '%s' qemud channel", QEMU_CHANNEL_NAME );
+
+    if ( socketpair( AF_LOCAL, SOCK_STREAM, 0, state->control ) < 0 ) {
+        ALOGE("could not create thread control socket pair: %s", strerror(errno));
+        goto Fail;
+    }
+
+    state->thread = callbacks->create_thread_cb( "gps_state_thread", gps_state_thread, state );
+
+    if ( !state->thread ) {
+        ALOGE("could not create gps thread: %s", strerror(errno));
+        goto Fail;
+    }
+
+    state->callbacks = *callbacks;
+
+    D("gps state initialized");
+    return;
+
+Fail:
+    gps_state_done( state );
+}
+
+
+/*****************************************************************/
+/*****************************************************************/
+/*****                                                       *****/
+/*****       I N T E R F A C E                               *****/
+/*****                                                       *****/
+/*****************************************************************/
+/*****************************************************************/
+
+
+static int
+qemu_gps_init(GpsCallbacks* callbacks)
+{
+    GpsState*  s = _gps_state;
+
+    if (!s->init)
+        gps_state_init(s, callbacks);
+
+    if (s->fd < 0)
+        return -1;
+
+    return 0;
+}
+
+static void
+qemu_gps_cleanup(void)
+{
+    GpsState*  s = _gps_state;
+
+    if (s->init)
+        gps_state_done(s);
+}
+
+
+static int
+qemu_gps_start()
+{
+    GpsState*  s = _gps_state;
+
+    if (!s->init) {
+        D("%s: called with uninitialized state !!", __FUNCTION__);
+        return -1;
+    }
+
+    D("%s: called", __FUNCTION__);
+    gps_state_start(s);
+    return 0;
+}
+
+
+static int
+qemu_gps_stop()
+{
+    GpsState*  s = _gps_state;
+
+    if (!s->init) {
+        D("%s: called with uninitialized state !!", __FUNCTION__);
+        return -1;
+    }
+
+    D("%s: called", __FUNCTION__);
+    gps_state_stop(s);
+    return 0;
+}
+
+
+static int
+qemu_gps_inject_time(GpsUtcTime time, int64_t timeReference, int uncertainty)
+{
+    return 0;
+}
+
+static int
+qemu_gps_inject_location(double latitude, double longitude, float accuracy)
+{
+    return 0;
+}
+
+static void
+qemu_gps_delete_aiding_data(GpsAidingData flags)
+{
+}
+
+static int qemu_gps_set_position_mode(GpsPositionMode mode, int fix_frequency)
+{
+    // FIXME - support fix_frequency
+    return 0;
+}
+
+static const void*
+qemu_gps_get_extension(const char* name)
+{
+    // no extensions supported
+    return NULL;
+}
+
+static const GpsInterface  qemuGpsInterface = {
+    sizeof(GpsInterface),
+    qemu_gps_init,
+    qemu_gps_start,
+    qemu_gps_stop,
+    qemu_gps_cleanup,
+    qemu_gps_inject_time,
+    qemu_gps_inject_location,
+    qemu_gps_delete_aiding_data,
+    qemu_gps_set_position_mode,
+    qemu_gps_get_extension,
+};
+
+const GpsInterface* gps__get_gps_interface(struct gps_device_t* dev)
+{
+    return &qemuGpsInterface;
+}
+
+static int open_gps(const struct hw_module_t* module, char const* name,
+        struct hw_device_t** device)
+{
+    struct gps_device_t *dev = malloc(sizeof(struct gps_device_t));
+    memset(dev, 0, sizeof(*dev));
+
+    dev->common.tag = HARDWARE_DEVICE_TAG;
+    dev->common.version = 0;
+    dev->common.module = (struct hw_module_t*)module;
+//    dev->common.close = (int (*)(struct hw_device_t*))close_lights;
+    dev->get_gps_interface = gps__get_gps_interface;
+
+    *device = (struct hw_device_t*)dev;
+    return 0;
+}
+
+
+static struct hw_module_methods_t gps_module_methods = {
+    .open = open_gps
+};
+
+struct hw_module_t HAL_MODULE_INFO_SYM = {
+    .tag = HARDWARE_MODULE_TAG,
+    .version_major = 1,
+    .version_minor = 0,
+    .id = GPS_HARDWARE_MODULE_ID,
+    .name = "Goldfish GPS Module",
+    .author = "The Android Open Source Project",
+    .methods = &gps_module_methods,
+};
diff --git a/libqemu/test_guest_1.c b/libqemu/test_guest_1.c
new file mode 100644
index 0000000..1a81000
--- /dev/null
+++ b/libqemu/test_guest_1.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+/* This program uses a QEMUD pipe to exchange data with a test
+ * server. It's very simple:
+ *
+ *    for count in range(0,100):
+ *       msg = "Hello Word " + count
+ *       qemud_pipe_send(msg)
+ *       qemud_pipe_recv(msg2)
+ *       if (msg != msg2):
+ *          error()
+ *
+ *
+ * See test_host_1.c for the corresponding server code, which simply
+ * sends back anything it receives from the client.
+ */
+#include "test_util.h"
+#include <errno.h>
+#include <string.h>
+#include <stddef.h>
+#include <stdio.h>
+
+#define  PIPE_NAME  "pingpong"
+
+
+int main(void)
+{
+    Pipe  pipe[1];
+    const int maxCount = 100;
+    int port = 8012;
+
+#if 0
+    if (pipe_openSocket(pipe, port) < 0) {
+        fprintf(stderr, "Could not open tcp socket!\n");
+        return 1;
+    }
+    printf("Connected to tcp:host:%d\n", port);
+#else
+    if (pipe_openQemuPipe(pipe, PIPE_NAME) < 0) {
+        fprintf(stderr, "Could not open '%s' pipe: %s\n", PIPE_NAME, strerror(errno));
+        return 1;
+    }
+    printf("Connected to '%s' pipe\n", PIPE_NAME);
+#endif
+
+    char  buff[64];
+    char  buff2[64];
+    int   count;
+    double time0 = now_secs();
+    size_t total = 0;
+
+    for (count = 0; count < maxCount; count++) {
+        /* First, send a small message */
+        int  len = snprintf(buff, sizeof(buff), "Hello World %d\n", count);
+        printf("%4d: Sending %d bytes\n", count, len);
+        int ret = pipe_send(pipe, buff, len);
+        if (ret < 0) {
+            fprintf(stderr,"Sending %d bytes failed: %s\n", len, strerror(errno));
+            return 1;
+        }
+
+        total += len;
+
+        /* The server is supposed to send the message back */
+        ret = pipe_recv(pipe, buff2, len);
+        if (ret < 0) {
+            fprintf(stderr, "Receiving failed (ret=%d): %s\n", ret, strerror(errno));
+            return 3;
+        }
+        printf("%4d: Received %d bytes\n", count, ret);
+        /* Check the message's content */
+        if (ret != len) {
+            fprintf(stderr, "Message size mismatch sent=%d received=%d\n", len, ret);
+            return 5;
+        }
+        if (memcmp(buff, buff2, len) != 0) {
+            fprintf(stderr, "Message content mismatch!\n");
+            return 6;
+        }
+    }
+
+    double time1 = now_secs();
+
+    printf("Closing pipe\n");
+    pipe_close(pipe);
+
+    printf("Bandwidth: %g MB/s, %g bytes in %g seconds.\n",
+           total*1.0 / (1024.*1024.*(time1-time0)), 1.0*total, time1-time0);
+
+    return 0;
+}
diff --git a/libqemu/test_guest_2.c b/libqemu/test_guest_2.c
new file mode 100644
index 0000000..c834098
--- /dev/null
+++ b/libqemu/test_guest_2.c
@@ -0,0 +1,240 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+/* This program benchmarks a QEMUD pipe to exchange data with a test
+ * server.
+ *
+ * See test_host_1.c for the corresponding server code, which simply
+ * sends back anything it receives from the client.
+ */
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include "test_util.h"
+
+#define  PIPE_NAME  "pingpong"
+
+char* progname;
+
+static void usage(int code)
+{
+    printf("Usage: %s [options]\n\n", progname);
+    printf(
+      "Valid options are:\n\n"
+      "  -? -h --help  Print this message\n"
+      "  -pipe <name>  Use pipe name (default: " PIPE_NAME ")\n"
+      "  -tcp <port>   Use local tcp port\n"
+      "  -size <size>  Specify packet size\n"
+      "\n"
+    );
+    exit(code);
+}
+
+int main(int argc, char** argv)
+{
+    Pipe        pipe[1];
+    const char* tcpPort = NULL;
+    int         localPort = 0;
+    const char* pipeName = NULL;
+    const char* packetSize = NULL;
+    int         port = 8012;
+    int         maxCount   = 1000;
+    int         bufferSize = 16384;
+    uint8_t*    buffer;
+    uint8_t*    buffer2;
+    int         nn, count;
+    double      time0, time1;
+
+    /* Extract program name */
+    {
+        char* p = strrchr(argv[0], '/');
+        if (p == NULL)
+            progname = argv[0];
+        else
+            progname = p+1;
+    }
+
+    /* Parse options */
+    while (argc > 1 && argv[1][0] == '-') {
+        char* arg = argv[1];
+        if (!strcmp(arg, "-?") || !strcmp(arg, "-h") || !strcmp(arg, "--help")) {
+            usage(0);
+        } else if (!strcmp(arg, "-pipe")) {
+            if (argc < 3) {
+                fprintf(stderr, "-pipe option needs an argument! See --help for details.\n");
+                exit(1);
+            }
+            argc--;
+            argv++;
+            pipeName = argv[1];
+        } else if (!strcmp(arg, "-tcp")) {
+            if (argc < 3) {
+                fprintf(stderr, "-tcp option needs an argument! See --help for details.\n");
+                exit(1);
+            }
+            argc--;
+            argv++;
+            tcpPort = argv[1];
+        } else if (!strcmp(arg, "-size")) {
+            if (argc < 3) {
+                fprintf(stderr, "-tcp option needs an argument! See --help for details.\n");
+                exit(1);
+            }
+            argc--;
+            argv++;
+            packetSize = argv[1];
+        } else {
+            fprintf(stderr, "UNKNOWN OPTION: %s\n\n", arg);
+            usage(1);
+        }
+        argc--;
+        argv++;
+    }
+
+    /* Check arguments */
+    if (tcpPort && pipeName) {
+        fprintf(stderr, "You can't use both -pipe and -tcp at the same time\n");
+        exit(2);
+    }
+
+    if (tcpPort != NULL) {
+        localPort = atoi(tcpPort);
+        if (localPort <= 0 || localPort > 65535) {
+            fprintf(stderr, "Invalid port number: %s\n", tcpPort);
+            exit(2);
+        }
+    } else if (pipeName == NULL) {
+        /* Use default pipe name */
+        pipeName = PIPE_NAME;
+    }
+
+    if (packetSize != NULL) {
+        int  size = atoi(packetSize);
+        if (size <= 0) {
+            fprintf(stderr, "Invalid byte size: %s\n", packetSize);
+            exit(3);
+        }
+        bufferSize = size;
+    }
+
+    /* Open the pipe */
+    if (tcpPort != NULL) {
+        if (pipe_openSocket(pipe, localPort) < 0) {
+            fprintf(stderr, "Could not open tcp socket!\n");
+            return 1;
+        }
+        printf("Connected to tcp:localhost:%d\n", port);
+    }
+    else {
+        if (pipe_openQemuPipe(pipe, pipeName) < 0) {
+            fprintf(stderr, "Could not open '%s' pipe: %s\n", pipeName, strerror(errno));
+            return 1;
+        }
+        printf("Connected to '%s' pipe\n", pipeName);
+    }
+
+    /* Allocate buffers, setup their data */
+    buffer  = malloc(bufferSize);
+    buffer2 = malloc(bufferSize);
+
+    for (nn = 0; nn < bufferSize; nn++) {
+        buffer[nn] = (uint8_t)nn;
+    }
+
+    /* Do the work! */
+    time0 = now_secs();
+
+    for (count = 0; count < maxCount; count++) {
+        int ret = pipe_send(pipe, buffer, bufferSize);
+        int pos, len;
+
+        if (ret < 0) {
+            fprintf(stderr,"%d: Sending %d bytes failed: %s\n", count, bufferSize, strerror(errno));
+            return 1;
+        }
+
+#if 1
+        /* The server is supposed to send the message back */
+        pos = 0;
+        len = bufferSize;
+        while (len > 0) {
+            ret = pipe_recv(pipe, buffer2 + pos, len);
+            if (ret < 0) {
+                fprintf(stderr, "Receiving failed (ret=%d): %s\n", ret, strerror(errno));
+                return 3;
+            }
+            if (ret == 0) {
+                fprintf(stderr, "Disconnection while receiving!\n");
+                return 4;
+            }
+            pos += ret;
+            len -= ret;
+        }
+
+        if (memcmp(buffer, buffer2, bufferSize) != 0) {
+            fprintf(stderr, "Message content mismatch!\n");
+            const int maxAvail = 16;
+            const int maxLines = 12;
+            int numLines = 0;
+            for (nn = 0; nn < bufferSize; ) {
+                int avail = bufferSize - nn;
+                int mm;
+                if (avail > maxAvail)
+                    avail = maxAvail;
+
+                if (memcmp(buffer+nn, buffer2+nn, avail) != 0) {
+                    if (++numLines >= maxLines) {
+                        printf(".... to be continued ...\n");
+                        break;
+                    }
+                    printf("%04x:", nn);
+
+                    for (mm = 0; mm < avail; mm++)
+                        printf(" %02x", buffer[nn+mm]);
+                    for ( ; mm < maxAvail; mm++ )
+                        printf("   ");
+
+                    printf( " -- " );
+
+                    for (mm = 0; mm < avail; mm++)
+                        printf(" %02x", buffer2[nn+mm]);
+
+                    printf ("\n");
+                }
+                nn += avail;
+            }
+            return 6;
+        }
+
+#endif
+
+        if (count > 0 && (count % 200) == 0) {
+            printf("... %d\n", count);
+        }
+    }
+
+    time1 = now_secs();
+
+    printf("Closing pipe\n");
+    pipe_close(pipe);
+
+    printf("Total time: %g seconds\n", time1 - time0);
+    printf("Total bytes: %g bytes\n", 1.0*maxCount*bufferSize);
+    printf("Bandwidth: %g MB/s\n", (maxCount*bufferSize/(1024.0*1024.0))/(time1 - time0) );
+    return 0;
+}
diff --git a/libqemu/test_host_1.c b/libqemu/test_host_1.c
new file mode 100644
index 0000000..8e32bf2
--- /dev/null
+++ b/libqemu/test_host_1.c
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+/* This program is used to test the QEMUD fast pipes.
+ * See external/qemu/docs/ANDROID-QEMUD-PIPES.TXT for details.
+ *
+ * The program acts as a simple TCP server that accepts data and sends
+ * them back to the client as is.
+ */
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+/* Default port number */
+#define  DEFAULT_PORT  8012
+#define  DEFAULT_PATH  "/tmp/libqemu-socket"
+
+/* Try to execute x, looping around EINTR errors. */
+#undef TEMP_FAILURE_RETRY
+#define TEMP_FAILURE_RETRY(exp) ({         \
+    typeof (exp) _rc;                      \
+    do {                                   \
+        _rc = (exp);                       \
+    } while (_rc == -1 && errno == EINTR); \
+    _rc; })
+
+#define TFR TEMP_FAILURE_RETRY
+
+/* Close a socket, preserving the value of errno */
+static void
+socket_close(int  sock)
+{
+    int  old_errno = errno;
+    close(sock);
+    errno = old_errno;
+}
+
+/* Create a server socket bound to a loopback port */
+static int
+socket_loopback_server( int port, int type )
+{
+    struct sockaddr_in  addr;
+
+    int  sock = socket(AF_INET, type, 0);
+    if (sock < 0) {
+        return -1;
+    }
+
+    memset(&addr, 0, sizeof(addr));
+    addr.sin_family      = AF_INET;
+    addr.sin_port        = htons(port);
+    addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+
+    int n = 1;
+    setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n));
+
+    if (TFR(bind(sock, (struct sockaddr*)&addr, sizeof(addr))) < 0) {
+        socket_close(sock);
+        return -1;
+    }
+
+    if (type == SOCK_STREAM) {
+        if (TFR(listen(sock, 4)) < 0) {
+            socket_close(sock);
+            return -1;
+        }
+    }
+
+    return sock;
+}
+
+static int
+socket_unix_server( const char* path, int type )
+{
+    struct sockaddr_un  addr;
+
+    int  sock = socket(AF_UNIX, type, 0);
+    if (sock < 0) {
+        return -1;
+    }
+
+    memset(&addr, 0, sizeof(addr));
+    addr.sun_family = AF_UNIX;
+    snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", path);
+
+    unlink(addr.sun_path);
+
+    printf("Unix path: '%s'\n", addr.sun_path);
+
+    int n = 1;
+    setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n));
+
+    if (TFR(bind(sock, (struct sockaddr*)&addr, sizeof(addr))) < 0) {
+        socket_close(sock);
+        return -1;
+    }
+
+    if (type == SOCK_STREAM) {
+        if (TFR(listen(sock, 4)) < 0) {
+            socket_close(sock);
+            return -1;
+        }
+    }
+
+    return sock;
+}
+
+char* progname;
+
+static void usage(int code)
+{
+    printf("Usage: %s [options]\n\n", progname);
+    printf(
+      "Valid options are:\n\n"
+      "  -? -h --help  Print this message\n"
+      "  -unix <path>  Use unix server socket\n"
+      "  -tcp <port>   Use local tcp port (default %d)\n"
+      "\n", DEFAULT_PORT
+    );
+    exit(code);
+}
+
+/* Main program */
+int main(int argc, char** argv)
+{
+    int sock, client;
+    int port = DEFAULT_PORT;
+    const char* path = NULL;
+    const char* tcpPort = NULL;
+
+    /* Extract program name */
+    {
+        char* p = strrchr(argv[0], '/');
+        if (p == NULL)
+            progname = argv[0];
+        else
+            progname = p+1;
+    }
+
+    /* Parse options */
+    while (argc > 1 && argv[1][0] == '-') {
+        char* arg = argv[1];
+        if (!strcmp(arg, "-?") || !strcmp(arg, "-h") || !strcmp(arg, "--help")) {
+            usage(0);
+        } else if (!strcmp(arg, "-unix")) {
+            if (argc < 3) {
+                fprintf(stderr, "-unix option needs an argument! See --help for details.\n");
+                exit(1);
+            }
+            argc--;
+            argv++;
+            path = argv[1];
+        } else if (!strcmp(arg, "-tcp")) {
+            if (argc < 3) {
+                fprintf(stderr, "-tcp option needs an argument! See --help for details.\n");
+                exit(1);
+            }
+            argc--;
+            argv++;
+            tcpPort = argv[1];
+        } else {
+            fprintf(stderr, "UNKNOWN OPTION: %s\n\n", arg);
+            usage(1);
+        }
+        argc--;
+        argv++;
+    }
+
+    if (path != NULL) {
+        printf("Starting pipe test server on unix path: %s\n", path);
+        sock = socket_unix_server( path, SOCK_STREAM );
+    } else {
+        printf("Starting pipe test server on local port %d\n", port);
+        sock = socket_loopback_server( port, SOCK_STREAM );
+    }
+    if (sock < 0) {
+        fprintf(stderr, "Could not start server: %s\n", strerror(errno));
+        return 1;
+    }
+    printf("Server ready!\n");
+
+RESTART:
+    client = TFR(accept(sock, NULL, NULL));
+    if (client < 0) {
+        fprintf(stderr, "Server error: %s\n", strerror(errno));
+        return 2;
+    }
+    printf("Client connected!\n");
+
+    /* Now, accept any incoming data, and send it back */
+    for (;;) {
+        char  buff[32768], *p;
+        int   ret, count;
+
+        ret = TFR(read(client, buff, sizeof(buff)));
+        if (ret < 0) {
+            fprintf(stderr, "Client read error: %s\n", strerror(errno));
+            socket_close(client);
+            return 3;
+        }
+        if (ret == 0) {
+            break;
+        }
+        count = ret;
+        p     = buff;
+        //printf("   received: %d bytes\n", count);
+
+        while (count > 0) {
+            ret = TFR(write(client, p, count));
+            if (ret < 0) {
+                fprintf(stderr, "Client write error: %s\n", strerror(errno));
+                socket_close(client);
+                return 4;
+            }
+            //printf("   sent: %d bytes\n", ret);
+
+            p     += ret;
+            count -= ret;
+        }
+    }
+    printf("Client closed connection\n");
+    socket_close(client);
+    goto RESTART;
+
+    return 0;
+}
diff --git a/libqemu/test_host_2.c b/libqemu/test_host_2.c
new file mode 100644
index 0000000..46a9e8d
--- /dev/null
+++ b/libqemu/test_host_2.c
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+/* This program is used to test the QEMUD fast pipes.
+ * See external/qemu/docs/ANDROID-QEMUD-PIPES.TXT for details.
+ *
+ * The program acts as a simple TCP server that accepts any data and
+ * discards it immediately.
+ */
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+/* Default port number */
+#define  DEFAULT_PORT  8012
+
+/* Try to execute x, looping around EINTR errors. */
+#undef TEMP_FAILURE_RETRY
+#define TEMP_FAILURE_RETRY(exp) ({         \
+    typeof (exp) _rc;                      \
+    do {                                   \
+        _rc = (exp);                       \
+    } while (_rc == -1 && errno == EINTR); \
+    _rc; })
+
+#define TFR TEMP_FAILURE_RETRY
+
+/* Close a socket, preserving the value of errno */
+static void
+socket_close(int  sock)
+{
+    int  old_errno = errno;
+    close(sock);
+    errno = old_errno;
+}
+
+/* Create a server socket bound to a loopback port */
+static int
+socket_loopback_server( int port, int type )
+{
+    struct sockaddr_in  addr;
+
+    int  sock = socket(AF_INET, type, 0);
+    if (sock < 0) {
+        return -1;
+    }
+
+    memset(&addr, 0, sizeof(addr));
+    addr.sin_family      = AF_INET;
+    addr.sin_port        = htons(port);
+    addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+
+    int n = 1;
+    setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n));
+
+    if (TFR(bind(sock, (struct sockaddr*)&addr, sizeof(addr))) < 0) {
+        socket_close(sock);
+        return -1;
+    }
+
+    if (type == SOCK_STREAM) {
+        if (TFR(listen(sock, 4)) < 0) {
+            socket_close(sock);
+            return -1;
+        }
+    }
+
+    return sock;
+}
+
+/* Main program */
+int main(void)
+{
+    int sock, client;
+    int port = DEFAULT_PORT;
+
+    printf("Starting pipe test server on local port %d\n", port);
+    sock = socket_loopback_server( port, SOCK_STREAM );
+    if (sock < 0) {
+        fprintf(stderr, "Could not start server: %s\n", strerror(errno));
+        return 1;
+    }
+
+RESTART:
+    client = TFR(accept(sock, NULL, NULL));
+    if (client < 0) {
+        fprintf(stderr, "Server error: %s\n", strerror(errno));
+        return 2;
+    }
+    printf("Client connected!\n");
+
+    /* Now, accept any incoming data, and send it back */
+    for (;;) {
+        char  buff[8192], *p;
+        int   ret, count;
+
+        ret = TFR(read(client, buff, sizeof(buff)));
+        if (ret < 0) {
+            fprintf(stderr, "Client read error: %s\n", strerror(errno));
+            socket_close(client);
+            return 3;
+        }
+        if (ret == 0) {
+            break;
+        }
+    }
+    printf("Client closed connection\n");
+    socket_close(client);
+    goto RESTART;
+
+    return 0;
+}
diff --git a/libqemu/test_util.c b/libqemu/test_util.c
new file mode 100644
index 0000000..1696796
--- /dev/null
+++ b/libqemu/test_util.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <stddef.h>
+#include <stdio.h>
+#include "test_util.h"
+
+#ifdef __linux__
+#include <time.h>
+double now_secs(void)
+{
+    struct timespec  tm;
+    clock_gettime(CLOCK_MONOTONIC, &tm);
+    return (double)tm.tv_sec + (double)tm.tv_nsec/1e9;
+}
+#else
+#include <sys/time.h>
+double now_secs(void)
+{
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+    return tv.sec + (double)tv.usec/1e6;
+}
+#endif
+
+int
+pipe_openSocket( Pipe*  pipe, int port )
+{
+    static int           fd;
+    struct sockaddr_in  addr;
+
+    pipe->socket = -1;
+
+    fd = socket( AF_INET, SOCK_STREAM, 0 );
+    if (fd < 0) {
+        fprintf(stderr, "%s: Can't create socket!!\n", __FUNCTION__);
+        return -1;
+    }
+
+    memset(&addr, 0, sizeof(addr));
+    addr.sin_family      = AF_INET;
+    addr.sin_port        = htons(port);
+    addr.sin_addr.s_addr = htonl(0x0a000202);
+
+    if ( connect(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0 ) {
+        fprintf(stderr, "%s: Can't connect to tcp:local:%d: %s\n",
+                __FUNCTION__, port, strerror(errno));
+        close(fd);
+        return -1;
+    }
+
+    pipe->socket = fd;
+    return 0;
+}
+
+int
+pipe_openQemuPipe( Pipe*  pipe, const char* pipename )
+{
+    pipe->socket = qemu_pipe_open(pipename);
+    if (pipe->socket < 0) {
+        fprintf(stderr, "%s: Could not open '%s' pipe: %s\n", __FUNCTION__, pipename, strerror(errno));
+        return -1;
+    }
+    return 0;
+}
+
+int
+pipe_send( Pipe*  pipe, const void* buff, size_t  bufflen )
+{
+    int ret;
+    const uint8_t* ptr = buff;
+    while (bufflen > 0) {
+        ret = write(pipe->socket, ptr, bufflen);
+        if (ret < 0) {
+            if (errno == EINTR)
+                continue;
+            fprintf(stderr, "%s: error: %s\n", __FUNCTION__, strerror(errno));
+            return -1;
+        }
+        if (ret == 0) {
+            fprintf(stderr, "%s: disconnection!\n", __FUNCTION__);
+            return -1;
+        }
+        ptr     += ret;
+        bufflen -= ret;
+    }
+    return 0;
+}
+
+int
+pipe_recv( Pipe*  pipe, void* buff, size_t bufflen )
+{
+    int  ret;
+
+    for (;;) {
+        ret = read(pipe->socket, buff, bufflen);
+        if (ret < 0) {
+            if (errno == EINTR)
+                continue;
+            fprintf(stderr, "%s: error: %s\n", __FUNCTION__, strerror(errno));
+            return -1;
+        }
+        if (ret == 0) {
+            fprintf(stderr, "%s: disconnection!\n", __FUNCTION__);
+            return -1;
+        }
+        break;
+    }
+    return ret;
+}
+
+void
+pipe_close( Pipe*  pipe )
+{
+    if (pipe->socket >= 0) {
+        close(pipe->socket);
+        pipe->socket = -1;
+    }
+}
diff --git a/libqemu/test_util.h b/libqemu/test_util.h
new file mode 100644
index 0000000..28e5115
--- /dev/null
+++ b/libqemu/test_util.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+#ifndef TEST_UTIL_H
+#define TEST_UTIL_H
+
+#include <stddef.h>
+#include <hardware/qemu_pipe.h>
+
+
+double now_secs(void);
+
+typedef struct {
+    int  socket;
+} Pipe;
+
+int  pipe_openSocket( Pipe*  pipe, int port );
+int  pipe_openQemuPipe( Pipe*  pipe, const char* pipename );
+int  pipe_send( Pipe*  pipe, const void* buff, size_t  bufflen );
+int  pipe_recv( Pipe*  pipe, void* buff, size_t bufflen );
+void pipe_close( Pipe*  pipe );
+
+#endif /* TEST_UTIL_H */
diff --git a/libqemu/tests.mk b/libqemu/tests.mk
new file mode 100644
index 0000000..886973f
--- /dev/null
+++ b/libqemu/tests.mk
@@ -0,0 +1,30 @@
+# Build libqemu tests, included from main Android.mk
+
+# The first test program is a simple TCP server that will send back
+# anything it receives from the client.
+#
+include $(CLEAR_VARS)
+LOCAL_MODULE := test-libqemu-1
+LOCAL_SRC_FILES := test_host_1.c
+LOCAL_MODULE_TAGS := tests
+include $(BUILD_HOST_EXECUTABLE)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := test-libqemu-2
+LOCAL_SRC_FILES := test_host_2.c
+LOCAL_MODULE_TAGS := tests
+include $(BUILD_HOST_EXECUTABLE)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := test-libqemu-1
+LOCAL_SRC_FILES := test_guest_1.c test_util.c
+LOCAL_MODULE_TAGS := tests
+LOCAL_STATIC_LIBRARIES := libcutils
+include $(BUILD_EXECUTABLE)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := test-libqemu-2
+LOCAL_SRC_FILES := test_guest_2.c test_util.c
+LOCAL_MODULE_TAGS := tests
+LOCAL_STATIC_LIBRARIES := libcutils
+include $(BUILD_EXECUTABLE)
diff --git a/lights/Android.mk b/lights/Android.mk
new file mode 100644
index 0000000..3fa04ed
--- /dev/null
+++ b/lights/Android.mk
@@ -0,0 +1,26 @@
+# Copyright (C) 2011 The Android Open Source Project.
+#
+# Original code licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this software 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.
+
+LOCAL_PATH := $(call my-dir)
+
+# HAL module implemenation, not prelinked and stored in
+# hw/<LIGHTS_HARDWARE_MODULE_ID>.<ro.hardware>.so
+include $(CLEAR_VARS)
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
+LOCAL_SHARED_LIBRARIES := liblog libcutils
+LOCAL_SRC_FILES := lights_qemu.c
+LOCAL_MODULE := lights.goldfish
+LOCAL_CFLAGS += -DLIGHT_BACKLIGHT
+include $(BUILD_SHARED_LIBRARY)
diff --git a/lights/lights_qemu.c b/lights/lights_qemu.c
new file mode 100644
index 0000000..94fe8cc
--- /dev/null
+++ b/lights/lights_qemu.c
@@ -0,0 +1,213 @@
+/* Copyright (C) 2011 The Android Open Source Project
+ *
+ * Original code licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * This implements a lights hardware library for the Android emulator.
+ * the following code should be built as a shared library that will be
+ * placed into /system/lib/hw/lights.goldfish.so
+ *
+ * It will be loaded by the code in hardware/libhardware/hardware.c
+ * which is itself called from
+ * ./frameworks/base/services/jni/com_android_server_HardwareService.cpp
+ */
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#define LOG_TAG "Lights"
+#endif
+
+/* we connect with the emulator through the "hw-control" qemud service */
+#define  LIGHTS_SERVICE_NAME "hw-control"
+
+#include <cutils/log.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <hardware/lights.h>
+#include <hardware/qemud.h>
+
+/* Set to 1 to enable debug messages to the log */
+#define DEBUG 0
+#if DEBUG
+# define D(...) ALOGD(__VA_ARGS__)
+#else
+# define D(...) do{}while(0)
+#endif
+
+#define  E(...)  ALOGE(__VA_ARGS__)
+
+/* Get brightness(0~255) from state. */
+static int
+rgb_to_brightness( struct light_state_t const* state )
+{
+    int color = state->color & 0x00ffffff;
+    return ((77 * ((color >> 16) & 0x00ff))
+            + (150 * ((color >> 8) & 0x00ff)) + (29 * (color & 0x00ff))) >> 8;
+}
+
+/* set backlight brightness by LIGHTS_SERVICE_NAME service. */
+static int
+set_light_backlight( struct light_device_t* dev, struct light_state_t const* state )
+{
+    /* Get Lights service. */
+    int  fd = qemud_channel_open( LIGHTS_SERVICE_NAME );
+
+    if (fd < 0) {
+        E( "%s: no qemud connection", __FUNCTION__ );
+        return -1;
+    }
+
+    D( "%s: On/Off %d/%d flashMode %d brightnessMode %d"
+       " RGB = 0x%08x", __func__,
+       state->flashOnMS,
+       state->flashOffMS,
+       state->flashMode,
+       state->brightnessMode,
+       state->color );
+
+    int brightness = rgb_to_brightness( state );
+
+    char buffer[64];
+    snprintf( buffer, sizeof(buffer), "power:light:brightness:lcd_backlight:%d", brightness );
+    D( "%s: lcd_backlight command: %s", __FUNCTION__, buffer );
+
+    /* send backlight command to perform the backlight setting. */
+    if (qemud_channel_send( fd, buffer, -1 ) < 0) {
+        E( "%s: could not query lcd_backlight: %s", __FUNCTION__, strerror(errno) );
+        close( fd );
+        return -1;
+    }
+
+    close( fd );
+    return 0;
+}
+
+static int
+set_light_buttons( struct light_device_t* dev, struct light_state_t const* state )
+{
+    /* @Waiting for later implementation. */
+    D( "%s: Not implemented.", __FUNCTION__ );
+
+    return 0;
+}
+
+static int
+set_light_battery( struct light_device_t* dev, struct light_state_t const* state )
+{
+    /* @Waiting for later implementation. */
+    D( "%s: Not implemented.", __FUNCTION__ );
+
+    return 0;
+}
+
+static int
+set_light_keyboard( struct light_device_t* dev, struct light_state_t const* state )
+{
+    /* @Waiting for later implementation. */
+    D( "%s: Not implemented.", __FUNCTION__ );
+
+    return 0;
+}
+
+static int
+set_light_notifications( struct light_device_t* dev, struct light_state_t const* state )
+{
+    /* @Waiting for later implementation. */
+    D( "%s: Not implemented.", __FUNCTION__ );
+
+    return 0;
+}
+
+static int
+set_light_attention( struct light_device_t* dev, struct light_state_t const* state )
+{
+    /* @Waiting for later implementation. */
+    D( "%s: Not implemented.", __FUNCTION__ );
+
+    return 0;
+}
+
+/** Close the lights device */
+static int
+close_lights( struct light_device_t *dev )
+{
+    free( dev );
+
+    return 0;
+}
+
+/**
+ * module methods
+ */
+
+/** Open a new instance of a lights device using name */
+static int
+open_lights( const struct hw_module_t* module, char const *name,
+        struct hw_device_t **device )
+{
+    void* set_light;
+
+    if (0 == strcmp( LIGHT_ID_BACKLIGHT, name )) {
+        set_light = set_light_backlight;
+    } else if (0 == strcmp( LIGHT_ID_KEYBOARD, name )) {
+        set_light = set_light_keyboard;
+    } else if (0 == strcmp( LIGHT_ID_BUTTONS, name )) {
+        set_light = set_light_buttons;
+    } else if (0 == strcmp( LIGHT_ID_BATTERY, name )) {
+        set_light = set_light_battery;
+    } else if (0 == strcmp( LIGHT_ID_NOTIFICATIONS, name )) {
+        set_light = set_light_notifications;
+    } else if (0 == strcmp( LIGHT_ID_ATTENTION, name )) {
+        set_light = set_light_attention;
+    } else {
+        D( "%s: %s light isn't supported yet.", __FUNCTION__, name );
+        return -EINVAL;
+    }
+
+    struct light_device_t *dev = malloc( sizeof(struct light_device_t) );
+    if (dev == NULL) {
+        return -EINVAL;
+    }
+    memset( dev, 0, sizeof(*dev) );
+
+    dev->common.tag = HARDWARE_DEVICE_TAG;
+    dev->common.version = 0;
+    dev->common.module = (struct hw_module_t*)module;
+    dev->common.close = (int (*)(struct hw_device_t*))close_lights;
+    dev->set_light = set_light;
+
+    *device = (struct hw_device_t*)dev;
+    return 0;
+}
+
+static struct hw_module_methods_t lights_module_methods = {
+    .open =  open_lights,
+};
+
+/*
+ * The emulator lights Module
+ */
+struct hw_module_t HAL_MODULE_INFO_SYM = {
+    .tag = HARDWARE_MODULE_TAG,
+    .version_major = 1,
+    .version_minor = 0,
+    .id = LIGHTS_HARDWARE_MODULE_ID,
+    .name = "Goldfish lights Module",
+    .author = "The Android Open Source Project",
+    .methods = &lights_module_methods,
+};
diff --git a/opengl/Android.mk b/opengl/Android.mk
new file mode 100644
index 0000000..3a23395
--- /dev/null
+++ b/opengl/Android.mk
@@ -0,0 +1,66 @@
+# This is the top-level build file for the Android HW OpenGL ES emulation
+# in Android.
+#
+# You must define BUILD_EMULATOR_OPENGL to 'true' in your environment to
+# build the following files.
+#
+# Also define BUILD_EMULATOR_OPENGL_DRIVER to 'true' to build the gralloc
+# stuff as well.
+#
+ifeq (true,$(BUILD_EMULATOR_OPENGL))
+
+# Top-level for all modules
+EMUGL_PATH := $(call my-dir)
+
+# Directory containing common headers used by several modules
+# This is always set to a module's LOCAL_C_INCLUDES
+# See the definition of emugl-begin-module in common.mk
+#
+EMUGL_COMMON_INCLUDES := $(EMUGL_PATH)/host/include/libOpenglRender
+
+# common cflags used by several modules
+# This is always set to a module's LOCAL_CFLAGS
+# See the definition of emugl-begin-module in common.mk
+#
+EMUGL_COMMON_CFLAGS := -DWITH_GLES2
+
+# Uncomment the following line if you want to enable debug traces
+# in the GLES emulation libraries.
+# EMUGL_COMMON_CFLAGS += -DEMUGL_DEBUG=1
+
+# Include common definitions used by all the modules included later
+# in this build file. This contains the definition of all useful
+# emugl-xxxx functions.
+#
+include $(EMUGL_PATH)/common.mk
+
+# IMPORTANT: ORDER IS CRUCIAL HERE
+#
+# For the import/export feature to work properly, you must include
+# modules below in correct order. That is, if module B depends on
+# module A, then it must be included after module A below.
+#
+# This ensures that anything exported by module A will be correctly
+# be imported by module B when it is declared.
+#
+# Note that the build system will complain if you try to import a
+# module that hasn't been declared yet anyway.
+#
+
+include $(EMUGL_PATH)/shared/OpenglOsUtils/Android.mk
+include $(EMUGL_PATH)/shared/OpenglCodecCommon/Android.mk
+
+# System static libraries
+include $(EMUGL_PATH)/system/GLESv1_enc/Android.mk
+include $(EMUGL_PATH)/system/GLESv2_enc/Android.mk
+include $(EMUGL_PATH)/system/renderControl_enc/Android.mk
+include $(EMUGL_PATH)/system/OpenglSystemCommon/Android.mk
+
+# System shared libraries
+include $(EMUGL_PATH)/system/GLESv1/Android.mk
+include $(EMUGL_PATH)/system/GLESv2/Android.mk
+
+include $(EMUGL_PATH)/system/gralloc/Android.mk
+include $(EMUGL_PATH)/system/egl/Android.mk
+
+endif # BUILD_EMULATOR_OPENGL == true
diff --git a/opengl/README b/opengl/README
new file mode 100644
index 0000000..91050ed
--- /dev/null
+++ b/opengl/README
@@ -0,0 +1,3 @@
+This directory contains Android-side modules related to hardware OpenGL ES
+emulation. The host-side modules and documentation are in
+$ANDROID_BUILD_TOP/sdk/emulator/opengl.
diff --git a/opengl/common.mk b/opengl/common.mk
new file mode 100644
index 0000000..6dd503e
--- /dev/null
+++ b/opengl/common.mk
@@ -0,0 +1,240 @@
+# This top-level build file is included by all modules that implement
+# the hardware OpenGL ES emulation for Android.
+#
+# We use it to ensure that all sub-Makefiles are included in the right
+# order for various variable definitions and usage to happen in the correct
+# order.
+#
+
+# The following macros are used to start a new GLES emulation module.
+#
+# This will define LOCAL_MODULE as $1, plus a few other variables
+# needed by the build system (e.g. LOCAL_MODULE_TAGS, LOCAL_MODULE_CLASS...)
+#
+# NOTE: You still need to define LOCAL_PATH before this
+#
+# Usage example:
+#
+#   $(call emugl-begin-static-library,<name>)
+#       LOCAL_SRC_FILES := ....
+#       LOCAL_C_INCLUDES += ....
+#   $(call emugl-end-module)
+#
+emugl-begin-static-library = $(call emugl-begin-module,$1,STATIC_LIBRARY)
+emugl-begin-shared-library = $(call emugl-begin-module,$1,SHARED_LIBRARY)
+
+# Internal list of all declared modules (used for sanity checking)
+_emugl_modules :=
+_emugl_HOST_modules :=
+
+# do not use directly, see functions above instead
+emugl-begin-module = \
+    $(eval include $(CLEAR_VARS)) \
+    $(eval LOCAL_MODULE := $1) \
+    $(eval LOCAL_MODULE_CLASS := $(patsubst HOST_%,%,$(patsubst %EXECUTABLE,%EXECUTABLES,$(patsubst %LIBRARY,%LIBRARIES,$2)))) \
+    $(eval LOCAL_IS_HOST_MODULE := $(if $3,true,))\
+    $(eval LOCAL_C_INCLUDES := $(EMUGL_COMMON_INCLUDES)) \
+    $(eval LOCAL_CFLAGS := $(EMUGL_COMMON_CFLAGS)) \
+    $(eval LOCAL_PRELINK_MODULE := false)\
+    $(eval _EMUGL_INCLUDE_TYPE := $(BUILD_$2)) \
+    $(call _emugl-init-module,$1,$2,$3)
+
+# Used to end a module definition, see function definitions above
+emugl-end-module = \
+    $(eval include $(_EMUGL_INCLUDE_TYPE))\
+    $(eval _EMUGL_INCLUDE_TYPE :=) \
+    $(eval _emugl_$(_emugl_HOST)modules += $(_emugl_MODULE))\
+    $(if $(EMUGL_DEBUG),$(call emugl-dump-module))
+
+# Managing module exports and imports.
+#
+# A module can 'import' another module, by calling emugl-import. This will
+# make the current LOCAL_MODULE inherit various definitions exported from
+# the imported module.
+#
+# Module exports are defined by calling emugl-export. Here is an example:
+#
+#      $(call emugl-begin-static-library,foo)
+#      LOCAL_SRC_FILES := foo.c
+#      $(call emugl-export,C_INCLUDES,$(LOCAL_PATH))
+#      $(call emugl-export,SHARED_LIBRARIES,libcutils)
+#      $(call emugl-end-module)
+#
+#      $(call emugl-begin-shared-library,bar)
+#      LOCAL_SRC_FILES := bar.cpp
+#      $(call emugl-import,foo)
+#      $(call emugl-end-module)
+#
+# Here, we define a static library named 'foo' which exports an include
+# path and a shared library requirement, and a shared library 'bar' which
+# imports it.
+#
+# What this means is that:
+#
+#    - 'bar' will automatically inherit foo's LOCAL_PATH in its LOCAL_C_INCLUDES
+#    - 'bar' will automatically inherit libcutils in its own LOCAL_SHARED_LIBRARIES
+#
+# Note that order of declaration matters. If 'foo' is defined after 'bar' in
+# the example above, nothing will work correctly because dependencies are
+# computed at import time.
+#
+#
+# IMPORTANT: Imports are transitive, i.e. when module A imports B,
+#            it automatically imports anything imported by B too.
+
+# This is the list of recognized export types we support for now.
+EMUGL_EXPORT_TYPES := \
+    CFLAGS \
+    LDLIBS \
+    LDFLAGS \
+    C_INCLUDES \
+    SHARED_LIBRARIES \
+    STATIC_LIBRARIES \
+    ADDITIONAL_DEPENDENCIES
+
+# Initialize a module in our database
+# $1: Module name
+# $2: Module type
+# $3: "HOST" for a host module, empty for a target one.
+_emugl-init-module = \
+    $(eval _emugl_HOST := $(if $3,HOST_,))\
+    $(eval _emugl_MODULE := $(_emugl_HOST)$1)\
+    $(if $(filter $(_emugl_$(_emugl_HOST)modules),$(_emugl_MODULE)),\
+        $(error There is already a $(if $3,host,) module named $1!)\
+    )\
+    $(eval _mod = $(_emugl_MODULE)) \
+    $(eval _emugl.$(_mod).type := $(patsubst HOST_%,%,$2))\
+    $(eval _emugl.$(_mod).imports :=) \
+    $(eval _emugl,$(_mod).moved :=) \
+    $(foreach _type,$(EMUGL_EXPORT_TYPES),\
+        $(eval _emugl.$(_mod).export.$(_type) :=)\
+    )
+
+# Called to indicate that a module exports a given local variable for its
+# users. This also adds this to LOCAL_$1
+# $1: Local variable type (e.g. CFLAGS, LDLIBS, etc...)
+# $2: Value(s) to append to the export
+emugl-export = \
+    $(eval _emugl.$(_emugl_MODULE).export.$1 += $2)\
+    $(eval LOCAL_$1 := $2 $(LOCAL_$1))
+
+emugl-export-outer = \
+    $(eval _emugl.$(_emugl_MODULE).export.$1 += $2)
+
+# Called to indicate that a module imports the exports of another module
+# $1: list of modules to import
+#
+emugl-import = \
+    $(foreach _imod,$1,\
+        $(call _emugl-module-import,$(_emugl_HOST)$(_imod))\
+    )
+
+_emugl-module-import = \
+    $(eval _mod := $(_emugl_MODULE))\
+    $(if $(filter-out $(_emugl_$(_emugl_HOST)modules),$1),\
+        $(info Unknown imported emugles module: $1)\
+        $(if $(_emugl_HOST),\
+            $(eval _names := $(patsubst HOST_%,%,$(_emugl_HOST_modules))),\
+            $(eval _names := $(_emugl_modules))\
+        )\
+        $(info Please one of the following names: $(_names))\
+        $(error Aborting)\
+    )\
+    $(if $(filter-out $(_emugl.$(_mod).imports),$1),\
+        $(eval _emugl.$(_mod).imports += $1)\
+        $(foreach _sub,$(_emugl.$1.imports),\
+            $(call _emugl-module-import,$(_sub))\
+        )\
+        $(foreach _type,$(EMUGL_EXPORT_TYPES),\
+            $(eval LOCAL_$(_type) := $(_emugl.$1.export.$(_type)) $(LOCAL_$(_type)))\
+        )\
+        $(if $(filter EXECUTABLE SHARED_LIBRARY,$(_emugl.$(_emugl_MODULE).type)),\
+            $(if $(filter STATIC_LIBRARY,$(_emugl.$1.type)),\
+                $(eval LOCAL_STATIC_LIBRARIES := $(1:HOST_%=%) $(LOCAL_STATIC_LIBRARIES))\
+            )\
+            $(if $(filter SHARED_LIBRARY,$(_emugl.$1.type)),\
+                $(if $(_emugl.$1.moved),,\
+                  $(eval LOCAL_SHARED_LIBRARIES := $(1:HOST_%=%) $(LOCAL_SHARED_LIBRARIES))\
+                )\
+            )\
+        )\
+    )
+
+_emugl-dump-list = \
+    $(foreach _list_item,$(strip $1),$(info .    $(_list_item)))
+
+emugl-dump-module = \
+    $(info MODULE=$(_emugl_MODULE))\
+    $(info .  HOST=$(_emugl_HOST))\
+    $(info .  TYPE=$(_emugl.$(_emugl_MODULE).type))\
+    $(info .  IMPORTS=$(_emugl.$(_emugl_MODULE).imports))\
+    $(foreach _type,$(EMUGL_EXPORT_TYPES),\
+        $(if $(filter C_INCLUDES ADDITIONAL_DEPENDENCIES,$(_type)),\
+            $(info .  EXPORT.$(_type) :=)\
+            $(call _emugl-dump-list,$(_emugl.$(_emugl_MODULE).export.$(_type)))\
+            $(info .  LOCAL_$(_type)  :=)\
+            $(call _emugl-dump-list,$(LOCAL_$(_type)))\
+        ,\
+            $(info .  EXPORT.$(_type) := $(strip $(_emugl.$(_emugl_MODULE).export.$(_type))))\
+            $(info .  LOCAL_$(_type)  := $(strip $(LOCAL_$(_type))))\
+        )\
+    )\
+    $(info .  LOCAL_SRC_FILES := $(LOCAL_SRC_FILES))\
+
+# This function can be called to generate the wrapper source files.
+# LOCAL_MODULE and LOCAL_MODULE_CLASS must be defined or the build will abort.
+# Source files will be stored in the local intermediates directory that will
+# be automatically added to your LOCAL_C_INCLUDES.
+# Usage:
+#    $(call emugl-gen-wrapper,<input-dir>,<basename>)
+#
+emugl-gen-wrapper = \
+    $(eval _emugl_out := $(call local-intermediates-dir)) \
+    $(call emugl-gen-wrapper-generic,$(_emugl_out),$1,$2) \
+    $(call emugl-export,C_INCLUDES,$(_emugl_out))
+
+# DO NOT CALL DIRECTLY, USE emugl-gen-wrapper instead.
+#
+# The following function can be called to generate GL library wrapper
+# Usage is:
+#
+#  $(call emugl-gen-wrapper-generic,<dst-dir>,<src-dir>,<basename>)
+#
+#  <dst-dir> is the destination directory where the generated sources are stored
+#  <src-dir> is the source directory where to find <basename>.attrib, etc..
+#  <basename> is the emugen basename (see host/tools/emugen/README)
+#
+emugl-gen-wrapper-generic = $(eval $(emugl-gen-wrapper-generic-ev))
+
+define emugl-gen-wrapper-generic-ev
+_emugl_wrap := $$1/$$3
+_emugl_src  := $$2/$$3
+GEN := $$(_emugl_wrap)_wrapper_entry.cpp \
+       $$(_emugl_wrap)_wrapper_context.cpp \
+       $$(_emugl_wrap)_wrapper_context.h \
+       $$(_emugl_wrap)_wrapper_proc.h
+
+$$(GEN): PRIVATE_PATH := $$(LOCAL_PATH)
+$$(GEN): PRIVATE_CUSTOM_TOOL := $$(EMUGL_EMUGEN) -W $$1 -i $$2 $$3
+$$(GEN): $$(EMUGL_EMUGEN) $$(_emugl_src).attrib $$(_emugl_src).in $$(_emugl_src).types
+	$$(transform-generated-source)
+
+$$(call emugl-export,ADDITIONAL_DEPENDENCIES,$$(GEN))
+LOCAL_GENERATED_SOURCES += $$(GEN)
+LOCAL_C_INCLUDES += $$1
+
+#ifneq ($$(HOST_OS),windows)
+$$(call emugl-export,LDFLAGS,-ldl)
+#endif
+
+endef
+
+# Call this function when your shared library must be placed in a non-standard
+# library path (i.e. not under /system/lib
+# $1: library sub-path,relative to /system/lib
+# For example: $(call emugl-set-shared-library-subpath,egl)
+emugl-set-shared-library-subpath = \
+    $(eval LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/$1)\
+    $(eval LOCAL_UNSTRIPPED_PATH := $(TARGET_OUT_SHARED_LIBRARIES_UNSTRIPPED)/$1)\
+    $(eval _emugl.$(LOCAL_MODULE).moved := true)\
+    $(call emugl-export-outer,ADDITIONAL_DEPENDENCIES,$(LOCAL_MODULE_PATH)/$(LOCAL_MODULE)$(TARGET_SHLIB_SUFFIX))
diff --git a/opengl/host/include/libOpenglRender/IOStream.h b/opengl/host/include/libOpenglRender/IOStream.h
new file mode 100644
index 0000000..445ec17
--- /dev/null
+++ b/opengl/host/include/libOpenglRender/IOStream.h
@@ -0,0 +1,102 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#ifndef __IO_STREAM_H__
+#define __IO_STREAM_H__
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "ErrorLog.h"
+
+class IOStream {
+public:
+
+    IOStream(size_t bufSize) {
+        m_buf = NULL;
+        m_bufsize = bufSize;
+        m_free = 0;
+    }
+
+    virtual void *allocBuffer(size_t minSize) = 0;
+    virtual int commitBuffer(size_t size) = 0;
+    virtual const unsigned char *readFully( void *buf, size_t len) = 0;
+    virtual const unsigned char *read( void *buf, size_t *inout_len) = 0;
+    virtual int writeFully(const void* buf, size_t len) = 0;
+
+    virtual ~IOStream() {
+
+        // NOTE: m_buf is 'owned' by the child class thus we expect it to be released by it
+    }
+
+    unsigned char *alloc(size_t len) {
+
+        if (m_buf && len > m_free) {
+            if (flush() < 0) {
+                ERR("Failed to flush in alloc\n");
+                return NULL; // we failed to flush so something is wrong
+            }
+        }
+
+        if (!m_buf || len > m_bufsize) {
+            int allocLen = m_bufsize < len ? len : m_bufsize;
+            m_buf = (unsigned char *)allocBuffer(allocLen);
+            if (!m_buf) {
+                ERR("Alloc (%u bytes) failed\n", allocLen);
+                return NULL;
+            }
+            m_bufsize = m_free = allocLen;
+        }
+
+        unsigned char *ptr;
+
+        ptr = m_buf + (m_bufsize - m_free);
+        m_free -= len;
+
+        return ptr;
+    }
+
+    int flush() {
+
+        if (!m_buf || m_free == m_bufsize) return 0;
+
+        int stat = commitBuffer(m_bufsize - m_free);
+        m_buf = NULL;
+        m_free = 0;
+        return stat;
+    }
+
+    const unsigned char *readback(void *buf, size_t len) {
+        flush();
+        return readFully(buf, len);
+    }
+
+
+private:
+    unsigned char *m_buf;
+    size_t m_bufsize;
+    size_t m_free;
+};
+
+//
+// When a client opens a connection to the renderer, it should
+// send unsigned int value indicating the "clientFlags".
+// The following are the bitmask of the clientFlags.
+// currently only one bit is used which flags the server
+// it should exit.
+//
+#define IOSTREAM_CLIENT_EXIT_SERVER      1
+
+#endif
diff --git a/opengl/shared/OpenglCodecCommon/Android.mk b/opengl/shared/OpenglCodecCommon/Android.mk
new file mode 100644
index 0000000..df9b39a
--- /dev/null
+++ b/opengl/shared/OpenglCodecCommon/Android.mk
@@ -0,0 +1,23 @@
+# This build script corresponds to a library containing many definitions
+# common to both the guest and the host. They relate to
+#
+LOCAL_PATH := $(call my-dir)
+
+commonSources := \
+        GLClientState.cpp \
+        GLSharedGroup.cpp \
+        glUtils.cpp \
+        SocketStream.cpp \
+        TcpStream.cpp \
+        TimeUtils.cpp
+
+### CodecCommon  guest ##############################################
+$(call emugl-begin-static-library,libOpenglCodecCommon)
+
+LOCAL_SRC_FILES := $(commonSources)
+
+LOCAL_CFLAGS += -DLOG_TAG=\"eglCodecCommon\"
+
+$(call emugl-export,SHARED_LIBRARIES,libcutils libutils)
+$(call emugl-export,C_INCLUDES,$(LOCAL_PATH))
+$(call emugl-end-module)
diff --git a/opengl/shared/OpenglCodecCommon/ErrorLog.h b/opengl/shared/OpenglCodecCommon/ErrorLog.h
new file mode 100644
index 0000000..6f41fd7
--- /dev/null
+++ b/opengl/shared/OpenglCodecCommon/ErrorLog.h
@@ -0,0 +1,37 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#ifndef _ERROR_LOG_H_
+#define _ERROR_LOG_H_
+
+#if (HAVE_ANDROID_OS == 1)
+#    include <cutils/log.h>
+#    define ERR(...)    ALOGE(__VA_ARGS__)
+#    ifdef EMUGL_DEBUG
+#        define DBG(...)    ALOGD(__VA_ARGS__)
+#    else
+#        define DBG(...)    ((void)0)
+#    endif
+#else
+#     include <stdio.h>
+#    define ERR(...)    fprintf(stderr, __VA_ARGS__)
+#    ifdef EMUGL_DEBUG
+#        define DBG(...)    fprintf(stderr, __VA_ARGS__)
+#    else
+#        define DBG(...)    ((void)0)
+#    endif
+#endif
+
+#endif
diff --git a/opengl/shared/OpenglCodecCommon/FixedBuffer.h b/opengl/shared/OpenglCodecCommon/FixedBuffer.h
new file mode 100644
index 0000000..30b9a80
--- /dev/null
+++ b/opengl/shared/OpenglCodecCommon/FixedBuffer.h
@@ -0,0 +1,53 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#ifndef _FIXED_BUFFER_H
+#define _FIXED_BUFFER_H
+
+class FixedBuffer {
+public:
+    FixedBuffer(size_t initialSize = 0) {
+        m_buffer = NULL;
+        m_bufferLen = 0;
+        alloc(m_bufferLen);
+    }
+
+    ~FixedBuffer() {
+        delete [] m_buffer;
+        m_bufferLen = 0;
+    }
+
+    void * alloc(size_t size) {
+        if (m_bufferLen >= size)
+            return (void *)(m_buffer);
+
+        if (m_buffer != NULL)
+            delete[] m_buffer;
+
+        m_bufferLen = size;
+        m_buffer = new unsigned char[m_bufferLen];
+        if (m_buffer == NULL)
+            m_bufferLen = 0;
+
+        return m_buffer;
+    }
+    void *ptr() { return m_buffer; }
+    size_t len() { return m_bufferLen; }
+private:
+    unsigned char *m_buffer;
+    size_t m_bufferLen;
+};
+
+#endif
diff --git a/opengl/shared/OpenglCodecCommon/GLClientState.cpp b/opengl/shared/OpenglCodecCommon/GLClientState.cpp
new file mode 100644
index 0000000..9795490
--- /dev/null
+++ b/opengl/shared/OpenglCodecCommon/GLClientState.cpp
@@ -0,0 +1,417 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#include "GLClientState.h"
+#include "ErrorLog.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "glUtils.h"
+#include <cutils/log.h>
+
+#ifndef MAX
+#define MAX(a, b) ((a) < (b) ? (b) : (a))
+#endif
+
+GLClientState::GLClientState(int nLocations)
+{
+    if (nLocations < LAST_LOCATION) {
+        nLocations = LAST_LOCATION;
+    }
+    m_nLocations = nLocations;
+    m_states = new VertexAttribState[m_nLocations];
+    for (int i = 0; i < m_nLocations; i++) {
+        m_states[i].enabled = 0;
+        m_states[i].enableDirty = false;
+    }
+    m_currentArrayVbo = 0;
+    m_currentIndexVbo = 0;
+    // init gl constans;
+    m_states[VERTEX_LOCATION].glConst = GL_VERTEX_ARRAY;
+    m_states[NORMAL_LOCATION].glConst = GL_NORMAL_ARRAY;
+    m_states[COLOR_LOCATION].glConst = GL_COLOR_ARRAY;
+    m_states[POINTSIZE_LOCATION].glConst = GL_POINT_SIZE_ARRAY_OES;
+    m_states[TEXCOORD0_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
+    m_states[TEXCOORD1_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
+    m_states[TEXCOORD2_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
+    m_states[TEXCOORD3_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
+    m_states[TEXCOORD4_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
+    m_states[TEXCOORD5_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
+    m_states[TEXCOORD6_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
+    m_states[TEXCOORD7_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
+    m_states[MATRIXINDEX_LOCATION].glConst = GL_MATRIX_INDEX_ARRAY_OES;
+    m_states[WEIGHT_LOCATION].glConst = GL_WEIGHT_ARRAY_OES;
+    m_activeTexture = 0;
+    m_currentProgram = 0;
+
+    m_pixelStore.unpack_alignment = 4;
+    m_pixelStore.pack_alignment = 4;
+
+    memset(m_tex.unit, 0, sizeof(m_tex.unit));
+    m_tex.activeUnit = &m_tex.unit[0];
+    m_tex.textures = NULL;
+    m_tex.numTextures = 0;
+    m_tex.allocTextures = 0;
+}
+
+GLClientState::~GLClientState()
+{
+    delete m_states;
+}
+
+void GLClientState::enable(int location, int state)
+{
+    if (!validLocation(location)) {
+        return;
+    }
+
+    m_states[location].enableDirty |= (state != m_states[location].enabled);
+    m_states[location].enabled = state;
+}
+
+void GLClientState::setState(int location, int size, GLenum type, GLboolean normalized, GLsizei stride, const void *data)
+{
+    if (!validLocation(location)) {
+        return;
+    }
+    m_states[location].size = size;
+    m_states[location].type = type;
+    m_states[location].stride = stride;
+    m_states[location].data = (void*)data;
+    m_states[location].bufferObject = m_currentArrayVbo;
+    m_states[location].elementSize = glSizeof(type) * size;
+    m_states[location].normalized = normalized;
+}
+
+void GLClientState::setBufferObject(int location, GLuint id)
+{
+    if (!validLocation(location)) {
+        return;
+    }
+
+    m_states[location].bufferObject = id;
+}
+
+const GLClientState::VertexAttribState * GLClientState::getState(int location)
+{
+    if (!validLocation(location)) {
+        return NULL;
+    }
+    return & m_states[location];
+}
+
+const GLClientState::VertexAttribState * GLClientState::getStateAndEnableDirty(int location, bool *enableChanged)
+{
+    if (!validLocation(location)) {
+        return NULL;
+    }
+
+    if (enableChanged) {
+        *enableChanged = m_states[location].enableDirty;
+    }
+
+    m_states[location].enableDirty = false;
+    return & m_states[location];
+}
+
+int GLClientState::getLocation(GLenum loc)
+{
+    int retval;
+
+    switch(loc) {
+    case GL_VERTEX_ARRAY:
+        retval = int(VERTEX_LOCATION);
+        break;
+    case GL_NORMAL_ARRAY:
+        retval = int(NORMAL_LOCATION);
+        break;
+    case GL_COLOR_ARRAY:
+        retval = int(COLOR_LOCATION);
+        break;
+    case GL_POINT_SIZE_ARRAY_OES:
+        retval = int(POINTSIZE_LOCATION);
+        break;
+    case GL_TEXTURE_COORD_ARRAY:
+        retval = int (TEXCOORD0_LOCATION + m_activeTexture);
+        break;
+    case GL_MATRIX_INDEX_ARRAY_OES:
+        retval = int (MATRIXINDEX_LOCATION);
+        break;
+    case GL_WEIGHT_ARRAY_OES:
+        retval = int (WEIGHT_LOCATION);
+        break;
+    default:
+        retval = loc;
+    }
+    return retval;
+}
+
+void GLClientState::getClientStatePointer(GLenum pname, GLvoid** params)
+{
+    const GLClientState::VertexAttribState *state = NULL;
+    switch (pname) {
+    case GL_VERTEX_ARRAY_POINTER: {
+        state = getState(GLClientState::VERTEX_LOCATION);
+        break;
+        }
+    case GL_NORMAL_ARRAY_POINTER: {
+        state = getState(GLClientState::NORMAL_LOCATION);
+        break;
+        }
+    case GL_COLOR_ARRAY_POINTER: {
+        state = getState(GLClientState::COLOR_LOCATION);
+        break;
+        }
+    case GL_TEXTURE_COORD_ARRAY_POINTER: {
+        state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION);
+        break;
+        }
+    case GL_POINT_SIZE_ARRAY_POINTER_OES: {
+        state = getState(GLClientState::POINTSIZE_LOCATION);
+        break;
+        }
+    case GL_MATRIX_INDEX_ARRAY_POINTER_OES: {
+        state = getState(GLClientState::MATRIXINDEX_LOCATION);
+        break;
+        }
+    case GL_WEIGHT_ARRAY_POINTER_OES: {
+        state = getState(GLClientState::WEIGHT_LOCATION);
+        break;
+        }
+    }
+    if (state && params)
+        *params = state->data;
+}
+
+int GLClientState::setPixelStore(GLenum param, GLint value)
+{
+    int retval = 0;
+    switch(param) {
+    case GL_UNPACK_ALIGNMENT:
+        if (value == 1 || value == 2 || value == 4 || value == 8) {
+            m_pixelStore.unpack_alignment = value;
+        } else {
+            retval =  GL_INVALID_VALUE;
+        }
+        break;
+    case GL_PACK_ALIGNMENT:
+        if (value == 1 || value == 2 || value == 4 || value == 8) {
+            m_pixelStore.pack_alignment = value;
+        } else {
+            retval =  GL_INVALID_VALUE;
+        }
+        break;
+        default:
+            retval = GL_INVALID_ENUM;
+    }
+    return retval;
+}
+
+
+
+
+size_t GLClientState::pixelDataSize(GLsizei width, GLsizei height, GLenum format, GLenum type, int pack) const
+{
+    int pixelsize = glUtilsPixelBitSize(format, type) >> 3;
+
+    int alignment = pack ? m_pixelStore.pack_alignment : m_pixelStore.unpack_alignment;
+
+    if (pixelsize == 0 ) {
+        ERR("unknown pixel size: width: %d height: %d format: %d type: %d pack: %d align: %d\n",
+             width, height, format, type, pack, alignment);
+    }
+    size_t linesize = pixelsize * width;
+    size_t aligned_linesize = int(linesize / alignment) * alignment;
+    if (aligned_linesize < linesize) {
+        aligned_linesize += alignment;
+    }
+    return aligned_linesize * height;
+}
+
+GLenum GLClientState::setActiveTextureUnit(GLenum texture)
+{
+    GLuint unit = texture - GL_TEXTURE0;
+    if (unit >= MAX_TEXTURE_UNITS) {
+        return GL_INVALID_OPERATION;
+    }
+    m_tex.activeUnit = &m_tex.unit[unit];
+    return GL_NO_ERROR;
+}
+
+GLenum GLClientState::getActiveTextureUnit() const
+{
+    return GL_TEXTURE0 + (m_tex.activeUnit - &m_tex.unit[0]);
+}
+
+void GLClientState::enableTextureTarget(GLenum target)
+{
+    switch (target) {
+    case GL_TEXTURE_2D:
+        m_tex.activeUnit->enables |= (1u << TEXTURE_2D);
+        break;
+    case GL_TEXTURE_EXTERNAL_OES:
+        m_tex.activeUnit->enables |= (1u << TEXTURE_EXTERNAL);
+        break;
+    }
+}
+
+void GLClientState::disableTextureTarget(GLenum target)
+{
+    switch (target) {
+    case GL_TEXTURE_2D:
+        m_tex.activeUnit->enables &= ~(1u << TEXTURE_2D);
+        break;
+    case GL_TEXTURE_EXTERNAL_OES:
+        m_tex.activeUnit->enables &= ~(1u << TEXTURE_EXTERNAL);
+        break;
+    }
+}
+
+GLenum GLClientState::getPriorityEnabledTarget(GLenum allDisabled) const
+{
+    unsigned int enables = m_tex.activeUnit->enables;
+    if (enables & (1u << TEXTURE_EXTERNAL)) {
+        return GL_TEXTURE_EXTERNAL_OES;
+    } else if (enables & (1u << TEXTURE_2D)) {
+        return GL_TEXTURE_2D;
+    } else {
+        return allDisabled;
+    }
+}
+
+int GLClientState::compareTexId(const void* pid, const void* prec)
+{
+    const GLuint* id = (const GLuint*)pid;
+    const TextureRec* rec = (const TextureRec*)prec;
+    return (GLint)(*id) - (GLint)rec->id;
+}
+
+GLenum GLClientState::bindTexture(GLenum target, GLuint texture,
+        GLboolean* firstUse)
+{
+    GLboolean first = GL_FALSE;
+    TextureRec* texrec = NULL;
+    if (texture != 0) {
+        if (m_tex.textures) {
+            texrec = (TextureRec*)bsearch(&texture, m_tex.textures,
+                    m_tex.numTextures, sizeof(TextureRec), compareTexId);
+        }
+        if (!texrec) {
+            if (!(texrec = addTextureRec(texture, target))) {
+                return GL_OUT_OF_MEMORY;
+            }
+            first = GL_TRUE;
+        }
+        if (target != texrec->target) {
+            return GL_INVALID_OPERATION;
+        }
+    }
+
+    switch (target) {
+    case GL_TEXTURE_2D:
+        m_tex.activeUnit->texture[TEXTURE_2D] = texture;
+        break;
+    case GL_TEXTURE_EXTERNAL_OES:
+        m_tex.activeUnit->texture[TEXTURE_EXTERNAL] = texture;
+        break;
+    }
+
+    if (firstUse) {
+        *firstUse = first;
+    }
+
+    return GL_NO_ERROR;
+}
+
+GLClientState::TextureRec* GLClientState::addTextureRec(GLuint id,
+        GLenum target)
+{
+    if (m_tex.numTextures == m_tex.allocTextures) {
+        const GLuint MAX_TEXTURES = 0xFFFFFFFFu;
+
+        GLuint newAlloc;
+        if (MAX_TEXTURES - m_tex.allocTextures >= m_tex.allocTextures) {
+            newAlloc = MAX(4, 2 * m_tex.allocTextures);
+        } else {
+            if (m_tex.allocTextures == MAX_TEXTURES) {
+                return NULL;
+            }
+            newAlloc = MAX_TEXTURES;
+        }
+
+        TextureRec* newTextures = (TextureRec*)realloc(m_tex.textures,
+                newAlloc * sizeof(TextureRec));
+        if (!newTextures) {
+            return NULL;
+        }
+
+        m_tex.textures = newTextures;
+        m_tex.allocTextures = newAlloc;
+    }
+
+    TextureRec* tex = m_tex.textures + m_tex.numTextures;
+    TextureRec* prev = tex - 1;
+    while (tex != m_tex.textures && id < prev->id) {
+        *tex-- = *prev--;
+    }
+    tex->id = id;
+    tex->target = target;
+    m_tex.numTextures++;
+
+    return tex;
+}
+
+GLuint GLClientState::getBoundTexture(GLenum target) const
+{
+    switch (target) {
+    case GL_TEXTURE_2D:
+        return m_tex.activeUnit->texture[TEXTURE_2D];
+    case GL_TEXTURE_EXTERNAL_OES:
+        return m_tex.activeUnit->texture[TEXTURE_EXTERNAL];
+    default:
+        return 0;
+    }
+}
+
+void GLClientState::deleteTextures(GLsizei n, const GLuint* textures)
+{
+    // Updating the textures array could be made more efficient when deleting
+    // several textures:
+    // - compacting the array could be done in a single pass once the deleted
+    //   textures are marked, or
+    // - could swap deleted textures to the end and re-sort.
+    TextureRec* texrec;
+    for (const GLuint* texture = textures; texture != textures + n; texture++) {
+        texrec = (TextureRec*)bsearch(texture, m_tex.textures,
+                m_tex.numTextures, sizeof(TextureRec), compareTexId);
+        if (texrec) {
+            const TextureRec* end = m_tex.textures + m_tex.numTextures;
+            memmove(texrec, texrec + 1,
+                    (end - texrec - 1) * sizeof(TextureRec));
+            m_tex.numTextures--;
+
+            for (TextureUnit* unit = m_tex.unit;
+                 unit != m_tex.unit + MAX_TEXTURE_UNITS;
+                 unit++)
+            {
+                if (unit->texture[TEXTURE_2D] == *texture) {
+                    unit->texture[TEXTURE_2D] = 0;
+                } else if (unit->texture[TEXTURE_EXTERNAL] == *texture) {
+                    unit->texture[TEXTURE_EXTERNAL] = 0;
+                }
+            }
+        }
+    }
+}
diff --git a/opengl/shared/OpenglCodecCommon/GLClientState.h b/opengl/shared/OpenglCodecCommon/GLClientState.h
new file mode 100644
index 0000000..c86329b
--- /dev/null
+++ b/opengl/shared/OpenglCodecCommon/GLClientState.h
@@ -0,0 +1,441 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#ifndef _GL_CLIENT_STATE_H_
+#define _GL_CLIENT_STATE_H_
+
+#define GL_API
+#ifndef ANDROID
+#define GL_APIENTRY
+#define GL_APIENTRYP
+#endif
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "ErrorLog.h"
+#include "codec_defs.h"
+
+class GLClientState {
+public:
+    typedef enum {
+        VERTEX_LOCATION = 0,
+        NORMAL_LOCATION = 1,
+        COLOR_LOCATION = 2,
+        POINTSIZE_LOCATION = 3,
+        TEXCOORD0_LOCATION = 4,
+        TEXCOORD1_LOCATION = 5,
+        TEXCOORD2_LOCATION = 6,
+        TEXCOORD3_LOCATION = 7,
+        TEXCOORD4_LOCATION = 8,
+        TEXCOORD5_LOCATION = 9,
+        TEXCOORD6_LOCATION = 10,
+        TEXCOORD7_LOCATION = 11,
+        MATRIXINDEX_LOCATION = 12,
+        WEIGHT_LOCATION = 13,
+        LAST_LOCATION = 14
+    } StateLocation;
+
+    typedef struct {
+        GLint enabled;
+        GLint size;
+        GLenum type;
+        GLsizei stride;
+        void *data;
+        GLuint bufferObject;
+        GLenum glConst;
+        unsigned int elementSize;
+        bool enableDirty;  // true if any enable state has changed since last draw
+        bool normalized;
+    } VertexAttribState;
+
+    typedef struct {
+        int unpack_alignment;
+        int pack_alignment;
+    } PixelStoreState;
+
+    enum {
+        MAX_TEXTURE_UNITS = 32,
+    };
+
+public:
+    GLClientState(int nLocations = CODEC_MAX_VERTEX_ATTRIBUTES);
+    ~GLClientState();
+    int nLocations() { return m_nLocations; }
+    const PixelStoreState *pixelStoreState() { return &m_pixelStore; }
+    int setPixelStore(GLenum param, GLint value);
+    GLuint currentArrayVbo() { return m_currentArrayVbo; }
+    GLuint currentIndexVbo() { return m_currentIndexVbo; }
+    void enable(int location, int state);
+    void setState(int  location, int size, GLenum type, GLboolean normalized, GLsizei stride, const void *data);
+    void setBufferObject(int location, GLuint id);
+    const VertexAttribState  *getState(int location);
+    const VertexAttribState  *getStateAndEnableDirty(int location, bool *enableChanged);
+    int getLocation(GLenum loc);
+    void setActiveTexture(int texUnit) {m_activeTexture = texUnit; };
+    int getActiveTexture() const { return m_activeTexture; }
+
+    int bindBuffer(GLenum target, GLuint id)
+    {
+        int err = 0;
+        switch(target) {
+        case GL_ARRAY_BUFFER:
+            m_currentArrayVbo = id;
+            break;
+        case GL_ELEMENT_ARRAY_BUFFER:
+            m_currentIndexVbo = id;
+            break;
+        default:
+            err = -1;
+        }
+        return err;
+    }
+
+    int getBuffer(GLenum target)
+    {
+      int ret=0;
+      switch (target) {
+      case GL_ARRAY_BUFFER:
+          ret = m_currentArrayVbo;
+          break;
+      case GL_ELEMENT_ARRAY_BUFFER:
+          ret = m_currentIndexVbo;
+          break;
+      default:
+          ret = -1;
+      }
+      return ret;
+    }
+    size_t pixelDataSize(GLsizei width, GLsizei height, GLenum format, GLenum type, int pack) const;
+
+    void setCurrentProgram(GLint program) { m_currentProgram = program; }
+    GLint currentProgram() const { return m_currentProgram; }
+
+    /* OES_EGL_image_external
+     *
+     * These functions manipulate GL state which interacts with the
+     * OES_EGL_image_external extension, to support client-side emulation on
+     * top of host implementations that don't have it.
+     *
+     * Most of these calls should only be used with TEXTURE_2D or
+     * TEXTURE_EXTERNAL_OES texture targets; TEXTURE_CUBE_MAP or other extension
+     * targets should bypass this. An exception is bindTexture(), which should
+     * see all glBindTexture() calls for any target.
+     */
+
+    // glActiveTexture(GL_TEXTURE0 + i)
+    // Sets the active texture unit. Up to MAX_TEXTURE_UNITS are supported.
+    GLenum setActiveTextureUnit(GLenum texture);
+    GLenum getActiveTextureUnit() const;
+
+    // glEnable(GL_TEXTURE_(2D|EXTERNAL_OES))
+    void enableTextureTarget(GLenum target);
+
+    // glDisable(GL_TEXTURE_(2D|EXTERNAL_OES))
+    void disableTextureTarget(GLenum target);
+
+    // Implements the target priority logic:
+    // * Return GL_TEXTURE_EXTERNAL_OES if enabled, else
+    // * Return GL_TEXTURE_2D if enabled, else
+    // * Return the allDisabled value.
+    // For some cases passing GL_TEXTURE_2D for allDisabled makes callee code
+    // simpler; for other cases passing a recognizable enum like GL_ZERO or
+    // GL_INVALID_ENUM is appropriate.
+    GLenum getPriorityEnabledTarget(GLenum allDisabled) const;
+
+    // glBindTexture(GL_TEXTURE_*, ...)
+    // Set the target binding of the active texture unit to texture. Returns
+    // GL_NO_ERROR on success or GL_INVALID_OPERATION if the texture has
+    // previously been bound to a different target. If firstUse is not NULL,
+    // it is set to indicate whether this is the first use of the texture.
+    // For accurate error detection, bindTexture should be called for *all*
+    // targets, not just 2D and EXTERNAL_OES.
+    GLenum bindTexture(GLenum target, GLuint texture, GLboolean* firstUse);
+
+    // Return the texture currently bound to GL_TEXTURE_(2D|EXTERNAL_OES).
+    GLuint getBoundTexture(GLenum target) const;
+
+    // glDeleteTextures(...)
+    // Remove references to the to-be-deleted textures.
+    void deleteTextures(GLsizei n, const GLuint* textures);
+
+private:
+    PixelStoreState m_pixelStore;
+    VertexAttribState *m_states;
+    int m_nLocations;
+    GLuint m_currentArrayVbo;
+    GLuint m_currentIndexVbo;
+    int m_activeTexture;
+    GLint m_currentProgram;
+
+    bool validLocation(int location) { return (location >= 0 && location < m_nLocations); }
+
+    enum TextureTarget {
+        TEXTURE_2D = 0,
+        TEXTURE_EXTERNAL = 1,
+        TEXTURE_TARGET_COUNT
+    };
+    struct TextureUnit {
+        unsigned int enables;
+        GLuint texture[TEXTURE_TARGET_COUNT];
+    };
+    struct TextureRec {
+        GLuint id;
+        GLenum target;
+    };
+    struct TextureState {
+        TextureUnit unit[MAX_TEXTURE_UNITS];
+        TextureUnit* activeUnit;
+        TextureRec* textures;
+        GLuint numTextures;
+        GLuint allocTextures;
+    };
+    TextureState m_tex;
+
+    static int compareTexId(const void* pid, const void* prec);
+    TextureRec* addTextureRec(GLuint id, GLenum target);
+
+public:
+    void getClientStatePointer(GLenum pname, GLvoid** params);
+
+    template <class T>
+    int getVertexAttribParameter(GLuint index, GLenum param, T *ptr)
+    {
+        bool handled = true;
+        const VertexAttribState *vertexAttrib = getState(index);
+        if (vertexAttrib == NULL) {
+            ERR("getVeterxAttriParameter for non existant index %d\n", index);
+            // set gl error;
+            return handled;
+        }
+
+        switch(param) {
+        case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
+            *ptr = (T)(vertexAttrib->bufferObject);
+            break;
+        case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
+            *ptr = (T)(vertexAttrib->enabled);
+            break;
+        case GL_VERTEX_ATTRIB_ARRAY_SIZE:
+            *ptr = (T)(vertexAttrib->size);
+            break;
+        case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
+            *ptr = (T)(vertexAttrib->stride);
+            break;
+        case GL_VERTEX_ATTRIB_ARRAY_TYPE:
+            *ptr = (T)(vertexAttrib->type);
+            break;
+        case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
+            *ptr = (T)(vertexAttrib->normalized);
+            break;
+        case GL_CURRENT_VERTEX_ATTRIB:
+            handled = false;
+            break;
+        default:
+            handled = false;
+            ERR("unknown vertex-attrib parameter param %d\n", param);
+        }
+        return handled;
+    }
+
+    template <class T>
+    bool getClientStateParameter(GLenum param, T* ptr)
+    {
+        bool isClientStateParam = false;
+        switch (param) {
+        case GL_CLIENT_ACTIVE_TEXTURE: {
+            GLint tex = getActiveTexture() + GL_TEXTURE0;
+            *ptr = tex;
+            isClientStateParam = true;
+            break;
+            }
+        case GL_VERTEX_ARRAY_SIZE: {
+            const GLClientState::VertexAttribState *state = getState(GLClientState::VERTEX_LOCATION);
+            *ptr = state->size;
+            isClientStateParam = true;
+            break;
+            }
+        case GL_VERTEX_ARRAY_TYPE: {
+            const GLClientState::VertexAttribState *state = getState(GLClientState::VERTEX_LOCATION);
+            *ptr = state->type;
+            isClientStateParam = true;
+            break;
+            }
+        case GL_VERTEX_ARRAY_STRIDE: {
+            const GLClientState::VertexAttribState *state = getState(GLClientState::VERTEX_LOCATION);
+            *ptr = state->stride;
+            isClientStateParam = true;
+            break;
+            }
+        case GL_COLOR_ARRAY_SIZE: {
+            const GLClientState::VertexAttribState *state = getState(GLClientState::COLOR_LOCATION);
+            *ptr = state->size;
+            isClientStateParam = true;
+            break;
+            }
+        case GL_COLOR_ARRAY_TYPE: {
+            const GLClientState::VertexAttribState *state = getState(GLClientState::COLOR_LOCATION);
+            *ptr = state->type;
+            isClientStateParam = true;
+            break;
+            }
+        case GL_COLOR_ARRAY_STRIDE: {
+            const GLClientState::VertexAttribState *state = getState(GLClientState::COLOR_LOCATION);
+            *ptr = state->stride;
+            isClientStateParam = true;
+            break;
+            }
+        case GL_NORMAL_ARRAY_TYPE: {
+            const GLClientState::VertexAttribState *state = getState(GLClientState::NORMAL_LOCATION);
+            *ptr = state->type;
+            isClientStateParam = true;
+            break;
+            }
+        case GL_NORMAL_ARRAY_STRIDE: {
+            const GLClientState::VertexAttribState *state = getState(GLClientState::NORMAL_LOCATION);
+            *ptr = state->stride;
+            isClientStateParam = true;
+            break;
+            }
+        case GL_TEXTURE_COORD_ARRAY_SIZE: {
+            const GLClientState::VertexAttribState *state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION);
+            *ptr = state->size;
+            isClientStateParam = true;
+            break;
+            }
+        case GL_TEXTURE_COORD_ARRAY_TYPE: {
+            const GLClientState::VertexAttribState *state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION);
+            *ptr = state->type;
+            isClientStateParam = true;
+            break;
+            }
+        case GL_TEXTURE_COORD_ARRAY_STRIDE: {
+            const GLClientState::VertexAttribState *state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION);
+            *ptr = state->stride;
+            isClientStateParam = true;
+            break;
+            }
+        case GL_POINT_SIZE_ARRAY_TYPE_OES: {
+            const GLClientState::VertexAttribState *state = getState(GLClientState::POINTSIZE_LOCATION);
+            *ptr = state->type;
+            isClientStateParam = true;
+            break;
+            }
+        case GL_POINT_SIZE_ARRAY_STRIDE_OES: {
+            const GLClientState::VertexAttribState *state = getState(GLClientState::POINTSIZE_LOCATION);
+            *ptr = state->stride;
+            isClientStateParam = true;
+            break;
+            }
+        case GL_MATRIX_INDEX_ARRAY_SIZE_OES: {
+            const GLClientState::VertexAttribState *state = getState(GLClientState::MATRIXINDEX_LOCATION);
+            *ptr = state->size;
+            isClientStateParam = true;
+            break;
+            }
+        case GL_MATRIX_INDEX_ARRAY_TYPE_OES: {
+            const GLClientState::VertexAttribState *state = getState(GLClientState::MATRIXINDEX_LOCATION);
+            *ptr = state->type;
+            isClientStateParam = true;
+            break;
+            }
+        case GL_MATRIX_INDEX_ARRAY_STRIDE_OES: {
+            const GLClientState::VertexAttribState *state = getState(GLClientState::MATRIXINDEX_LOCATION);
+            *ptr = state->stride;
+            isClientStateParam = true;
+            break;
+            }
+        case GL_WEIGHT_ARRAY_SIZE_OES: {
+            const GLClientState::VertexAttribState *state = getState(GLClientState::WEIGHT_LOCATION);
+            *ptr = state->size;
+            isClientStateParam = true;
+            break;
+            }
+        case GL_WEIGHT_ARRAY_TYPE_OES: {
+            const GLClientState::VertexAttribState *state = getState(GLClientState::WEIGHT_LOCATION);
+            *ptr = state->type;
+            isClientStateParam = true;
+            break;
+            }
+        case GL_WEIGHT_ARRAY_STRIDE_OES: {
+            const GLClientState::VertexAttribState *state = getState(GLClientState::WEIGHT_LOCATION);
+            *ptr = state->stride;
+            isClientStateParam = true;
+            break;
+            }
+        case GL_VERTEX_ARRAY_BUFFER_BINDING: {
+            const GLClientState::VertexAttribState *state = getState(GLClientState::VERTEX_LOCATION);
+            *ptr = state->bufferObject;
+            isClientStateParam = true;
+            break;
+            }
+        case GL_NORMAL_ARRAY_BUFFER_BINDING: {
+            const GLClientState::VertexAttribState *state = getState(GLClientState::NORMAL_LOCATION);
+            *ptr = state->bufferObject;
+            isClientStateParam = true;
+            break;
+            }
+        case GL_COLOR_ARRAY_BUFFER_BINDING: {
+            const GLClientState::VertexAttribState *state = getState(GLClientState::COLOR_LOCATION);
+            *ptr = state->bufferObject;
+            isClientStateParam = true;
+            break;
+            }
+        case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING: {
+            const GLClientState::VertexAttribState *state = getState(getActiveTexture()+GLClientState::TEXCOORD0_LOCATION);
+            *ptr = state->bufferObject;
+            isClientStateParam = true;
+            break;
+            }
+        case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES: {
+            const GLClientState::VertexAttribState *state = getState(GLClientState::POINTSIZE_LOCATION);
+            *ptr = state->bufferObject;
+            isClientStateParam = true;
+            break;
+            }
+        case GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES: {
+            const GLClientState::VertexAttribState *state = getState(GLClientState::MATRIXINDEX_LOCATION);
+            *ptr = state->bufferObject;
+            isClientStateParam = true;
+            break;
+            }
+        case GL_WEIGHT_ARRAY_BUFFER_BINDING_OES: {
+            const GLClientState::VertexAttribState *state = getState(GLClientState::WEIGHT_LOCATION);
+            *ptr = state->bufferObject;
+            isClientStateParam = true;
+            break;
+            }
+        case GL_ARRAY_BUFFER_BINDING: {
+            int buffer = getBuffer(GL_ARRAY_BUFFER);
+            *ptr = buffer;
+            isClientStateParam = true;
+            break;
+            }
+        case GL_ELEMENT_ARRAY_BUFFER_BINDING: {
+            int buffer = getBuffer(GL_ELEMENT_ARRAY_BUFFER);
+            *ptr = buffer;
+            isClientStateParam = true;
+            break;
+            }
+        }
+        return isClientStateParam;
+    }
+
+};
+#endif
diff --git a/opengl/shared/OpenglCodecCommon/GLDecoderContextData.h b/opengl/shared/OpenglCodecCommon/GLDecoderContextData.h
new file mode 100644
index 0000000..23785ae
--- /dev/null
+++ b/opengl/shared/OpenglCodecCommon/GLDecoderContextData.h
@@ -0,0 +1,69 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#ifndef _GL_DECODER_CONTEXT_DATA_H_
+#define _GL_DECODER_CONTEXT_DATA_H_
+
+#include <assert.h>
+#include <string.h>
+#include "FixedBuffer.h"
+#include "codec_defs.h"
+
+class  GLDecoderContextData {
+public:
+    typedef enum  {
+        VERTEX_LOCATION = 0,
+        NORMAL_LOCATION = 1,
+        COLOR_LOCATION = 2,
+        POINTSIZE_LOCATION = 3,
+        TEXCOORD0_LOCATION = 4,
+        TEXCOORD1_LOCATION = 5,
+        TEXCOORD2_LOCATION = 6,
+        TEXCOORD3_LOCATION = 7,
+        TEXCOORD4_LOCATION = 8,
+        TEXCOORD5_LOCATION = 9,
+        TEXCOORD6_LOCATION = 10,
+        TEXCOORD7_LOCATION = 11,
+        MATRIXINDEX_LOCATION = 12,
+        WEIGHT_LOCATION = 13,
+        LAST_LOCATION = 14
+    } PointerDataLocation;
+
+    GLDecoderContextData(int nLocations = CODEC_MAX_VERTEX_ATTRIBUTES) :
+        m_nLocations(nLocations)
+    {
+        m_pointerData = new FixedBuffer[m_nLocations];
+    }
+
+    ~GLDecoderContextData() {
+        delete [] m_pointerData;
+    }
+
+    void storePointerData(unsigned int loc, void *data, size_t len) {
+
+        assert(loc < m_nLocations);
+        m_pointerData[loc].alloc(len);
+        memcpy(m_pointerData[loc].ptr(), data, len);
+    }
+    void *pointerData(unsigned int loc) {
+        assert(loc < m_nLocations);
+        return m_pointerData[loc].ptr();
+    }
+private:
+    FixedBuffer *m_pointerData;
+    int m_nLocations;
+};
+
+#endif
diff --git a/opengl/shared/OpenglCodecCommon/GLErrorLog.h b/opengl/shared/OpenglCodecCommon/GLErrorLog.h
new file mode 100644
index 0000000..5654aea
--- /dev/null
+++ b/opengl/shared/OpenglCodecCommon/GLErrorLog.h
@@ -0,0 +1,34 @@
+/*
+* Copyright 2011 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.
+*/
+
+#ifndef __GL_ERROR_LOG_H__
+#define __GL_ERROR_LOG_H__
+
+#include "ErrorLog.h"
+
+#ifdef CHECK_GL_ERROR
+void dbg(){}
+#define GET_GL_ERROR(gl)  \
+    {   \
+        int err = gl.glGetError();    \
+        if (err) { dbg(); ERR("Error: 0x%X in %s (%s:%d)\n", err, __FUNCTION__, __FILE__, __LINE__); }  \
+    }
+
+#else
+#define GET_GL_ERROR(gl)
+#endif
+
+#endif //__GL_ERROR_LOG_H__
diff --git a/opengl/shared/OpenglCodecCommon/GLSharedGroup.cpp b/opengl/shared/OpenglCodecCommon/GLSharedGroup.cpp
new file mode 100644
index 0000000..8504f7f
--- /dev/null
+++ b/opengl/shared/OpenglCodecCommon/GLSharedGroup.cpp
@@ -0,0 +1,469 @@
+/*
+* Copyright (C) 2011 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.
+*/
+
+#include "GLSharedGroup.h"
+
+/**** BufferData ****/
+
+BufferData::BufferData() : m_size(0) {};
+BufferData::BufferData(GLsizeiptr size, void * data) : m_size(size) 
+{
+    void * buffer = NULL;
+    if (size>0) buffer = m_fixedBuffer.alloc(size);
+    if (data) memcpy(buffer, data, size);
+}
+
+/**** ProgramData ****/
+ProgramData::ProgramData() : m_numIndexes(0),
+                             m_initialized(false),
+                             m_locShiftWAR(false)
+{
+    m_Indexes = NULL;
+}
+
+void ProgramData::initProgramData(GLuint numIndexes)
+{
+    m_initialized = true;
+    m_numIndexes = numIndexes;
+    delete[] m_Indexes;
+    m_Indexes = new IndexInfo[numIndexes];
+    m_locShiftWAR = false;
+}
+
+bool ProgramData::isInitialized()
+{
+    return m_initialized;
+}
+
+ProgramData::~ProgramData()
+{
+    delete[] m_Indexes;
+    m_Indexes = NULL;
+}
+
+void ProgramData::setIndexInfo(GLuint index, GLint base, GLint size, GLenum type)
+{   
+    if (index>=m_numIndexes)
+        return;
+    m_Indexes[index].base = base;
+    m_Indexes[index].size = size;
+    m_Indexes[index].type = type;
+    if (index > 0) {
+        m_Indexes[index].appBase = m_Indexes[index-1].appBase +
+                                   m_Indexes[index-1].size;
+    }
+    else {
+        m_Indexes[index].appBase = 0;
+    }
+    m_Indexes[index].hostLocsPerElement = 1;
+    m_Indexes[index].flags = 0;
+    m_Indexes[index].samplerValue = 0;
+}
+
+void ProgramData::setIndexFlags(GLuint index, GLuint flags)
+{
+    if (index >= m_numIndexes)
+        return;
+    m_Indexes[index].flags |= flags;
+}
+
+GLuint ProgramData::getIndexForLocation(GLint location)
+{
+    GLuint index = m_numIndexes;
+    GLint minDist = -1;
+    for (GLuint i=0;i<m_numIndexes;++i)
+    {
+        GLint dist = location - m_Indexes[i].base;
+        if (dist >= 0 && 
+            (minDist < 0 || dist < minDist)) {
+            index = i;
+            minDist = dist;
+        }
+    }
+    return index;
+}
+
+GLenum ProgramData::getTypeForLocation(GLint location)
+{
+    GLuint index = getIndexForLocation(location);
+    if (index<m_numIndexes) {
+        return m_Indexes[index].type;
+    }
+    return 0;
+}
+
+void ProgramData::setupLocationShiftWAR()
+{
+    m_locShiftWAR = false;
+    for (GLuint i=0; i<m_numIndexes; i++) {
+        if (0 != (m_Indexes[i].base & 0xffff)) {
+            return;
+        }
+    }
+    // if we have one uniform at location 0, we do not need the WAR.
+    if (m_numIndexes > 1) {
+        m_locShiftWAR = true;
+    }
+}
+
+GLint ProgramData::locationWARHostToApp(GLint hostLoc, GLint arrIndex)
+{
+    if (!m_locShiftWAR) return hostLoc;
+
+    GLuint index = getIndexForLocation(hostLoc);
+    if (index<m_numIndexes) {
+        if (arrIndex > 0) {
+            m_Indexes[index].hostLocsPerElement = 
+                              (hostLoc - m_Indexes[index].base) / arrIndex;
+        }
+        return m_Indexes[index].appBase + arrIndex;
+    }
+    return -1;
+}
+
+GLint ProgramData::locationWARAppToHost(GLint appLoc)
+{
+    if (!m_locShiftWAR) return appLoc;
+
+    for(GLuint i=0; i<m_numIndexes; i++) {
+        GLint elemIndex = appLoc - m_Indexes[i].appBase;
+        if (elemIndex >= 0 && elemIndex < m_Indexes[i].size) {
+            return m_Indexes[i].base +
+                   elemIndex * m_Indexes[i].hostLocsPerElement;
+        }
+    }
+    return -1;
+}
+
+GLint ProgramData::getNextSamplerUniform(GLint index, GLint* val, GLenum* target)
+{
+    for (GLint i = index + 1; i >= 0 && i < (GLint)m_numIndexes; i++) {
+        if (m_Indexes[i].type == GL_SAMPLER_2D) {
+            if (val) *val = m_Indexes[i].samplerValue;
+            if (target) {
+                if (m_Indexes[i].flags & INDEX_FLAG_SAMPLER_EXTERNAL) {
+                    *target = GL_TEXTURE_EXTERNAL_OES;
+                } else {
+                    *target = GL_TEXTURE_2D;
+                }
+            }
+            return i;
+        }
+    }
+    return -1;
+}
+
+bool ProgramData::setSamplerUniform(GLint appLoc, GLint val, GLenum* target)
+{
+    for (GLuint i = 0; i < m_numIndexes; i++) {
+        GLint elemIndex = appLoc - m_Indexes[i].appBase;
+        if (elemIndex >= 0 && elemIndex < m_Indexes[i].size) {
+            if (m_Indexes[i].type == GL_TEXTURE_2D) {
+                m_Indexes[i].samplerValue = val;
+                if (target) {
+                    if (m_Indexes[i].flags & INDEX_FLAG_SAMPLER_EXTERNAL) {
+                        *target = GL_TEXTURE_EXTERNAL_OES;
+                    } else {
+                        *target = GL_TEXTURE_2D;
+                    }
+                }
+                return true;
+            }
+        }
+    }
+    return false;
+}
+
+bool ProgramData::attachShader(GLuint shader)
+{
+    size_t n = m_shaders.size();
+    for (size_t i = 0; i < n; i++) {
+        if (m_shaders[i] == shader) {
+            return false;
+        }
+    }
+    // AKA m_shaders.push_back(), but that has an ambiguous call to insertAt()
+    // due to the default parameters. This is the desired insertAt() overload.
+    m_shaders.insertAt(shader, m_shaders.size(), 1);
+    return true;
+}
+
+bool ProgramData::detachShader(GLuint shader)
+{
+    size_t n = m_shaders.size();
+    for (size_t i = 0; i < n; i++) {
+        if (m_shaders[i] == shader) {
+            m_shaders.removeAt(i);
+            return true;
+        }
+    }
+    return false;
+}
+
+/***** GLSharedGroup ****/
+
+GLSharedGroup::GLSharedGroup() :
+    m_buffers(android::DefaultKeyedVector<GLuint, BufferData*>(NULL)),
+    m_programs(android::DefaultKeyedVector<GLuint, ProgramData*>(NULL)),
+    m_shaders(android::DefaultKeyedVector<GLuint, ShaderData*>(NULL))
+{
+}
+
+GLSharedGroup::~GLSharedGroup()
+{
+    m_buffers.clear();
+    m_programs.clear();
+}
+
+BufferData * GLSharedGroup::getBufferData(GLuint bufferId)
+{
+    android::AutoMutex _lock(m_lock);
+    return m_buffers.valueFor(bufferId);    
+}
+
+void GLSharedGroup::addBufferData(GLuint bufferId, GLsizeiptr size, void * data)
+{
+    android::AutoMutex _lock(m_lock);
+    m_buffers.add(bufferId, new BufferData(size, data));
+}
+
+void GLSharedGroup::updateBufferData(GLuint bufferId, GLsizeiptr size, void * data)
+{
+    android::AutoMutex _lock(m_lock);
+    m_buffers.replaceValueFor(bufferId, new BufferData(size, data));
+}
+
+GLenum GLSharedGroup::subUpdateBufferData(GLuint bufferId, GLintptr offset, GLsizeiptr size, void * data)
+{
+    android::AutoMutex _lock(m_lock);
+    BufferData * buf = m_buffers.valueFor(bufferId);
+    if ((!buf) || (buf->m_size < offset+size) || (offset < 0) || (size<0)) return GL_INVALID_VALUE; 
+
+    //it's safe to update now
+    memcpy((char*)buf->m_fixedBuffer.ptr() + offset, data, size);
+    return GL_NO_ERROR; 
+}
+
+void GLSharedGroup::deleteBufferData(GLuint bufferId)
+{
+    android::AutoMutex _lock(m_lock);
+    m_buffers.removeItem(bufferId);
+}
+
+void GLSharedGroup::addProgramData(GLuint program)
+{
+    android::AutoMutex _lock(m_lock);
+    ProgramData *pData = m_programs.valueFor(program);
+    if (pData) 
+    {   
+        m_programs.removeItem(program);
+        delete pData;
+    }
+
+    m_programs.add(program,new ProgramData());
+}
+
+void GLSharedGroup::initProgramData(GLuint program, GLuint numIndexes)
+{
+    android::AutoMutex _lock(m_lock);
+    ProgramData *pData = m_programs.valueFor(program);
+    if (pData)
+    {
+        pData->initProgramData(numIndexes);
+    }
+}
+
+bool GLSharedGroup::isProgramInitialized(GLuint program)
+{
+    android::AutoMutex _lock(m_lock);
+    ProgramData* pData = m_programs.valueFor(program);
+    if (pData) 
+    {
+        return pData->isInitialized();
+    }
+    return false;
+}
+
+void GLSharedGroup::deleteProgramData(GLuint program)
+{
+    android::AutoMutex _lock(m_lock);
+    ProgramData *pData = m_programs.valueFor(program);
+    if (pData)
+        delete pData;
+    m_programs.removeItem(program); 
+}
+
+void GLSharedGroup::attachShader(GLuint program, GLuint shader)
+{
+    android::AutoMutex _lock(m_lock);
+    ProgramData* programData = m_programs.valueFor(program);
+    ssize_t idx = m_shaders.indexOfKey(shader);
+    if (programData && idx >= 0) {
+        if (programData->attachShader(shader)) {
+            refShaderDataLocked(idx);
+        }
+    }
+}
+
+void GLSharedGroup::detachShader(GLuint program, GLuint shader)
+{
+    android::AutoMutex _lock(m_lock);
+    ProgramData* programData = m_programs.valueFor(program);
+    ssize_t idx = m_shaders.indexOfKey(shader);
+    if (programData && idx >= 0) {
+        if (programData->detachShader(shader)) {
+            unrefShaderDataLocked(idx);
+        }
+    }
+}
+
+void GLSharedGroup::setProgramIndexInfo(GLuint program, GLuint index, GLint base, GLint size, GLenum type, const char* name)
+{
+    android::AutoMutex _lock(m_lock);
+    ProgramData* pData = m_programs.valueFor(program);
+    if (pData)
+    {
+        pData->setIndexInfo(index,base,size,type);
+
+        if (type == GL_SAMPLER_2D) {
+            size_t n = pData->getNumShaders();
+            for (size_t i = 0; i < n; i++) {
+                GLuint shaderId = pData->getShader(i);
+                ShaderData* shader = m_shaders.valueFor(shaderId);
+                if (!shader) continue;
+                ShaderData::StringList::iterator nameIter = shader->samplerExternalNames.begin();
+                ShaderData::StringList::iterator nameEnd  = shader->samplerExternalNames.end();
+                while (nameIter != nameEnd) {
+                    if (*nameIter == name) {
+                        pData->setIndexFlags(index, ProgramData::INDEX_FLAG_SAMPLER_EXTERNAL);
+                        break;
+                    }
+                    ++nameIter;
+                }
+            }
+        }
+    }
+}
+
+GLenum GLSharedGroup::getProgramUniformType(GLuint program, GLint location)
+{
+    android::AutoMutex _lock(m_lock);
+    ProgramData* pData = m_programs.valueFor(program);
+    GLenum type=0;
+    if (pData) 
+    {
+        type = pData->getTypeForLocation(location);
+    }
+    return type;
+}
+
+bool  GLSharedGroup::isProgram(GLuint program)
+{
+    android::AutoMutex _lock(m_lock);
+    ProgramData* pData = m_programs.valueFor(program);
+    return (pData!=NULL);
+}
+
+void GLSharedGroup::setupLocationShiftWAR(GLuint program)
+{
+    android::AutoMutex _lock(m_lock);
+    ProgramData* pData = m_programs.valueFor(program);
+    if (pData) pData->setupLocationShiftWAR();
+}
+
+GLint GLSharedGroup::locationWARHostToApp(GLuint program, GLint hostLoc, GLint arrIndex)
+{
+    android::AutoMutex _lock(m_lock);
+    ProgramData* pData = m_programs.valueFor(program);
+    if (pData) return pData->locationWARHostToApp(hostLoc, arrIndex);
+    else return hostLoc;
+}
+
+GLint GLSharedGroup::locationWARAppToHost(GLuint program, GLint appLoc)
+{
+    android::AutoMutex _lock(m_lock);
+    ProgramData* pData = m_programs.valueFor(program);
+    if (pData) return pData->locationWARAppToHost(appLoc);
+    else return appLoc;
+}
+
+bool GLSharedGroup::needUniformLocationWAR(GLuint program)
+{
+    android::AutoMutex _lock(m_lock);
+    ProgramData* pData = m_programs.valueFor(program);
+    if (pData) return pData->needUniformLocationWAR();
+    return false;
+}
+
+GLint GLSharedGroup::getNextSamplerUniform(GLuint program, GLint index, GLint* val, GLenum* target) const
+{
+    android::AutoMutex _lock(m_lock);
+    ProgramData* pData = m_programs.valueFor(program);
+    return pData ? pData->getNextSamplerUniform(index, val, target) : -1;
+}
+
+bool GLSharedGroup::setSamplerUniform(GLuint program, GLint appLoc, GLint val, GLenum* target)
+{
+    android::AutoMutex _lock(m_lock);
+    ProgramData* pData = m_programs.valueFor(program);
+    return pData ? pData->setSamplerUniform(appLoc, val, target) : false;
+}
+
+bool GLSharedGroup::addShaderData(GLuint shader)
+{
+    android::AutoMutex _lock(m_lock);
+    ShaderData* data = new ShaderData;
+    if (data) {
+        if (m_shaders.add(shader, data) < 0) {
+            delete data;
+            data = NULL;
+        }
+        data->refcount = 1;
+    }
+    return data != NULL;
+}
+
+ShaderData* GLSharedGroup::getShaderData(GLuint shader)
+{
+    android::AutoMutex _lock(m_lock);
+    return m_shaders.valueFor(shader);
+}
+
+void GLSharedGroup::unrefShaderData(GLuint shader)
+{
+    android::AutoMutex _lock(m_lock);
+    ssize_t idx = m_shaders.indexOfKey(shader);
+    if (idx >= 0) {
+        unrefShaderDataLocked(idx);
+    }
+}
+
+void GLSharedGroup::refShaderDataLocked(ssize_t shaderIdx)
+{
+    assert(shaderIdx >= 0 && shaderIdx <= m_shaders.size());
+    ShaderData* data = m_shaders.valueAt(shaderIdx);
+    data->refcount++;
+}
+
+void GLSharedGroup::unrefShaderDataLocked(ssize_t shaderIdx)
+{
+    assert(shaderIdx >= 0 && shaderIdx <= m_shaders.size());
+    ShaderData* data = m_shaders.valueAt(shaderIdx);
+    if (--data->refcount == 0) {
+        delete data;
+        m_shaders.removeItemsAt(shaderIdx);
+    }
+}
diff --git a/opengl/shared/OpenglCodecCommon/GLSharedGroup.h b/opengl/shared/OpenglCodecCommon/GLSharedGroup.h
new file mode 100644
index 0000000..61b8f00
--- /dev/null
+++ b/opengl/shared/OpenglCodecCommon/GLSharedGroup.h
@@ -0,0 +1,143 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#ifndef _GL_SHARED_GROUP_H_
+#define _GL_SHARED_GROUP_H_
+
+#define GL_API
+#ifndef ANDROID
+#define GL_APIENTRY
+#define GL_APIENTRYP
+#endif
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "ErrorLog.h"
+#include <utils/KeyedVector.h>
+#include <utils/List.h>
+#include <utils/String8.h>
+#include <utils/threads.h>
+#include "FixedBuffer.h"
+#include "SmartPtr.h"
+
+struct BufferData {
+    BufferData();
+    BufferData(GLsizeiptr size, void * data);
+    GLsizeiptr  m_size;
+    FixedBuffer m_fixedBuffer;    
+};
+
+class ProgramData {
+private:
+    typedef struct _IndexInfo {
+        GLint base;
+        GLint size;
+        GLenum type;
+        GLint appBase;
+        GLint hostLocsPerElement;
+        GLuint flags;
+        GLint samplerValue; // only set for sampler uniforms
+    } IndexInfo;
+
+    GLuint m_numIndexes;
+    IndexInfo* m_Indexes;
+    bool m_initialized;
+    bool m_locShiftWAR;
+
+    android::Vector<GLuint> m_shaders;
+
+public:
+    enum {
+        INDEX_FLAG_SAMPLER_EXTERNAL = 0x00000001,
+    };
+
+    ProgramData();
+    void initProgramData(GLuint numIndexes);
+    bool isInitialized();
+    virtual ~ProgramData();
+    void setIndexInfo(GLuint index, GLint base, GLint size, GLenum type);
+    void setIndexFlags(GLuint index, GLuint flags);
+    GLuint getIndexForLocation(GLint location);
+    GLenum getTypeForLocation(GLint location);
+
+    bool needUniformLocationWAR() const { return m_locShiftWAR; }
+    void setupLocationShiftWAR();
+    GLint locationWARHostToApp(GLint hostLoc, GLint arrIndex);
+    GLint locationWARAppToHost(GLint appLoc);
+
+    GLint getNextSamplerUniform(GLint index, GLint* val, GLenum* target);
+    bool setSamplerUniform(GLint appLoc, GLint val, GLenum* target);
+
+    bool attachShader(GLuint shader);
+    bool detachShader(GLuint shader);
+    size_t getNumShaders() const { return m_shaders.size(); }
+    GLuint getShader(size_t i) const { return m_shaders[i]; }
+};
+
+struct ShaderData {
+    typedef android::List<android::String8> StringList;
+    StringList samplerExternalNames;
+    int refcount;
+};
+
+class GLSharedGroup {
+private:
+    android::DefaultKeyedVector<GLuint, BufferData*> m_buffers;
+    android::DefaultKeyedVector<GLuint, ProgramData*> m_programs;
+    android::DefaultKeyedVector<GLuint, ShaderData*> m_shaders;
+    mutable android::Mutex m_lock;
+
+    void refShaderDataLocked(ssize_t shaderIdx);
+    void unrefShaderDataLocked(ssize_t shaderIdx);
+
+public:
+    GLSharedGroup();
+    ~GLSharedGroup();
+    BufferData * getBufferData(GLuint bufferId);
+    void    addBufferData(GLuint bufferId, GLsizeiptr size, void * data);
+    void    updateBufferData(GLuint bufferId, GLsizeiptr size, void * data);
+    GLenum  subUpdateBufferData(GLuint bufferId, GLintptr offset, GLsizeiptr size, void * data);
+    void    deleteBufferData(GLuint);
+
+    bool    isProgram(GLuint program);
+    bool    isProgramInitialized(GLuint program);
+    void    addProgramData(GLuint program); 
+    void    initProgramData(GLuint program, GLuint numIndexes);
+    void    attachShader(GLuint program, GLuint shader);
+    void    detachShader(GLuint program, GLuint shader);
+    void    deleteProgramData(GLuint program);
+    void    setProgramIndexInfo(GLuint program, GLuint index, GLint base, GLint size, GLenum type, const char* name);
+    GLenum  getProgramUniformType(GLuint program, GLint location);
+    void    setupLocationShiftWAR(GLuint program);
+    GLint   locationWARHostToApp(GLuint program, GLint hostLoc, GLint arrIndex);
+    GLint   locationWARAppToHost(GLuint program, GLint appLoc);
+    bool    needUniformLocationWAR(GLuint program);
+    GLint   getNextSamplerUniform(GLuint program, GLint index, GLint* val, GLenum* target) const;
+    bool    setSamplerUniform(GLuint program, GLint appLoc, GLint val, GLenum* target);
+
+    bool    addShaderData(GLuint shader);
+    // caller must hold a reference to the shader as long as it holds the pointer
+    ShaderData* getShaderData(GLuint shader);
+    void    unrefShaderData(GLuint shader);
+};
+
+typedef SmartPtr<GLSharedGroup> GLSharedGroupPtr; 
+
+#endif //_GL_SHARED_GROUP_H_
diff --git a/opengl/shared/OpenglCodecCommon/Makefile b/opengl/shared/OpenglCodecCommon/Makefile
new file mode 100644
index 0000000..e8bf431
--- /dev/null
+++ b/opengl/shared/OpenglCodecCommon/Makefile
@@ -0,0 +1,13 @@
+
+ROOT=../..
+
+include $(ROOT)/make/commondefs
+
+CXXFILES = TcpStream.cpp GLClientState.cpp glUtils.cpp
+CXXINCS += -I$(ROOT)/libs/GLESv1 -I$(ROOT)/include
+
+LIBRARY_NAME = libcodecCommon.a
+
+include $(COMMONRULES)
+
+
diff --git a/opengl/shared/OpenglCodecCommon/SmartPtr.h b/opengl/shared/OpenglCodecCommon/SmartPtr.h
new file mode 100644
index 0000000..4bdfbe4
--- /dev/null
+++ b/opengl/shared/OpenglCodecCommon/SmartPtr.h
@@ -0,0 +1,167 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#ifndef __SMART_PTR_H
+#define __SMART_PTR_H
+
+#include <cutils/threads.h>
+#include <cutils/atomic.h>
+
+template <class T, bool threadSafe = false>
+class SmartPtr
+{
+public:
+    explicit SmartPtr(T* ptr = (T*)NULL) {
+        if (threadSafe) {
+            m_lock = new mutex_t;
+            mutex_init(m_lock);
+        }
+        else m_lock = NULL;
+
+        m_ptr = ptr;
+        if (ptr)
+           m_pRefCount = new int32_t(1);
+        else
+           m_pRefCount = NULL;
+    }
+
+    SmartPtr<T,threadSafe>(const SmartPtr<T,false>& rhs) {
+        if (threadSafe) {
+            m_lock = new mutex_t;
+            mutex_init(m_lock);
+        }
+        else m_lock = NULL;
+
+        m_pRefCount = rhs.m_pRefCount;
+        m_ptr       = rhs.m_ptr;
+        use();
+    }
+
+    SmartPtr<T,threadSafe>(SmartPtr<T,true>& rhs) {
+        if (threadSafe) {
+            m_lock = new mutex_t;
+            mutex_init(m_lock);
+        }
+        else m_lock = NULL;
+
+        if (rhs.m_lock) mutex_lock(rhs.m_lock);
+        m_pRefCount = rhs.m_pRefCount;
+        m_ptr       = rhs.m_ptr;
+        use();
+        if (rhs.m_lock) mutex_unlock(rhs.m_lock);
+    }
+
+    ~SmartPtr() {
+        if (m_lock) mutex_lock(m_lock);
+        release();
+        if (m_lock)
+        {
+            mutex_unlock(m_lock);
+            mutex_destroy(m_lock);
+            delete m_lock;
+        }
+    }
+
+    T* Ptr() const {
+        return m_ptr;
+    }
+
+    const T* constPtr() const
+    {
+        return m_ptr;
+    }
+
+    T* operator->() const {
+        return m_ptr;
+    }
+
+    T& operator*() const {
+        return *m_ptr;
+    }
+
+    operator void*() const {
+        return (void *)m_ptr;
+    }
+
+    // This gives STL lists something to compare.
+    bool operator <(const SmartPtr<T>& t1) const {
+        return m_ptr < t1.m_ptr;
+    }
+
+    SmartPtr<T,threadSafe>& operator=(const SmartPtr<T,false>& rhs)
+    {
+        if (m_ptr == rhs.m_ptr)
+            return *this;
+
+        if (m_lock) mutex_lock(m_lock);
+        release();
+        m_pRefCount = rhs.m_pRefCount;
+        m_ptr       = rhs.m_ptr;
+        use();
+        if (m_lock) mutex_unlock(m_lock);
+
+        return *this;
+    }
+
+    SmartPtr<T,threadSafe>& operator=(SmartPtr<T,true>& rhs)
+    {
+        if (m_ptr == rhs.m_ptr)
+            return *this;
+
+        if (m_lock) mutex_lock(m_lock);
+        release();
+        if (rhs.m_lock) mutex_lock(rhs.m_lock);
+        m_pRefCount = rhs.m_pRefCount;
+        m_ptr       = rhs.m_ptr;
+        use();
+        if (rhs.m_lock) mutex_unlock(rhs.m_lock);
+        if (m_lock) mutex_unlock(m_lock);
+
+        return *this;
+    }
+
+private:
+    int32_t  *m_pRefCount;
+    mutex_t  *m_lock;
+    T* m_ptr;
+
+    // Increment the reference count on this pointer by 1.
+    int use() {
+        if (!m_pRefCount) return 0;
+        return android_atomic_inc(m_pRefCount) + 1;
+    }
+
+    // Decrement the reference count on the pointer by 1.
+    // If the reference count goes to (or below) 0, the pointer is deleted.
+    int release() {
+        if (!m_pRefCount) return 0;
+
+        int iVal = android_atomic_dec(m_pRefCount);
+        if (iVal > 1)
+            return iVal - 1;
+
+        delete m_pRefCount;
+        m_pRefCount = NULL;
+
+        if (m_ptr) {
+            delete m_ptr;
+            m_ptr = NULL;
+        }
+        return 0;
+    }
+
+};
+
+#endif // of  __SMART_PTR_H
diff --git a/opengl/shared/OpenglCodecCommon/SocketStream.cpp b/opengl/shared/OpenglCodecCommon/SocketStream.cpp
new file mode 100644
index 0000000..f7a2314
--- /dev/null
+++ b/opengl/shared/OpenglCodecCommon/SocketStream.cpp
@@ -0,0 +1,168 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#include "SocketStream.h"
+#include <cutils/sockets.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#ifndef _WIN32
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <sys/un.h>
+#else
+#include <ws2tcpip.h>
+#endif
+
+SocketStream::SocketStream(size_t bufSize) :
+    IOStream(bufSize),
+    m_sock(-1),
+    m_bufsize(bufSize),
+    m_buf(NULL)
+{
+}
+
+SocketStream::SocketStream(int sock, size_t bufSize) :
+    IOStream(bufSize),
+    m_sock(sock),
+    m_bufsize(bufSize),
+    m_buf(NULL)
+{
+}
+
+SocketStream::~SocketStream()
+{
+    if (m_sock >= 0) {
+#ifdef _WIN32
+        closesocket(m_sock);
+#else
+        ::close(m_sock);
+#endif
+    }
+    if (m_buf != NULL) {
+        free(m_buf);
+        m_buf = NULL;
+    }
+}
+
+
+void *SocketStream::allocBuffer(size_t minSize)
+{
+    size_t allocSize = (m_bufsize < minSize ? minSize : m_bufsize);
+    if (!m_buf) {
+        m_buf = (unsigned char *)malloc(allocSize);
+    }
+    else if (m_bufsize < allocSize) {
+        unsigned char *p = (unsigned char *)realloc(m_buf, allocSize);
+        if (p != NULL) {
+            m_buf = p;
+            m_bufsize = allocSize;
+        } else {
+            ERR("%s: realloc (%zu) failed\n", __FUNCTION__, allocSize);
+            free(m_buf);
+            m_buf = NULL;
+            m_bufsize = 0;
+        }
+    }
+
+    return m_buf;
+};
+
+int SocketStream::commitBuffer(size_t size)
+{
+    return writeFully(m_buf, size);
+}
+
+int SocketStream::writeFully(const void* buffer, size_t size)
+{
+    if (!valid()) return -1;
+
+    size_t res = size;
+    int retval = 0;
+
+    while (res > 0) {
+        ssize_t stat = ::send(m_sock, (const char *)buffer + (size - res), res, 0);
+        if (stat < 0) {
+            if (errno != EINTR) {
+                retval =  stat;
+                ERR("%s: failed: %s\n", __FUNCTION__, strerror(errno));
+                break;
+            }
+        } else {
+            res -= stat;
+        }
+    }
+    return retval;
+}
+
+const unsigned char *SocketStream::readFully(void *buf, size_t len)
+{
+    const unsigned char* ret = NULL;
+    if (!valid()) return NULL;
+    if (!buf) {
+      return NULL;  // do not allow NULL buf in that implementation
+    }
+    size_t res = len;
+    while (res > 0) {
+        ssize_t stat = ::recv(m_sock, (char *)(buf) + len - res, res, 0);
+        if (stat > 0) {
+            res -= stat;
+            continue;
+        }
+        if (stat == 0 || errno != EINTR) { // client shutdown or error
+            return NULL;
+        }
+    }
+    return (const unsigned char *)buf;
+}
+
+const unsigned char *SocketStream::read( void *buf, size_t *inout_len)
+{
+    if (!valid()) return NULL;
+    if (!buf) {
+      return NULL;  // do not allow NULL buf in that implementation
+    }
+
+    int n;
+    do {
+        n = recv(buf, *inout_len);
+    } while( n < 0 && errno == EINTR );
+
+    if (n > 0) {
+        *inout_len = n;
+        return (const unsigned char *)buf;
+    }
+
+    return NULL;
+}
+
+int SocketStream::recv(void *buf, size_t len)
+{
+    if (!valid()) return int(ERR_INVALID_SOCKET);
+    int res = 0;
+    while(true) {
+        res = ::recv(m_sock, (char *)buf, len, 0);
+        if (res < 0) {
+            if (errno == EINTR) {
+                continue;
+            }
+        }
+        break;
+    }
+    return res;
+}
diff --git a/opengl/shared/OpenglCodecCommon/SocketStream.h b/opengl/shared/OpenglCodecCommon/SocketStream.h
new file mode 100644
index 0000000..3a501b4
--- /dev/null
+++ b/opengl/shared/OpenglCodecCommon/SocketStream.h
@@ -0,0 +1,50 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#ifndef __SOCKET_STREAM_H
+#define __SOCKET_STREAM_H
+
+#include <stdlib.h>
+#include "IOStream.h"
+
+class SocketStream : public IOStream {
+public:
+    typedef enum { ERR_INVALID_SOCKET = -1000 } SocketStreamError;
+
+    explicit SocketStream(size_t bufsize = 10000);
+    virtual ~SocketStream();
+
+    virtual int listen(unsigned short port) = 0;
+    virtual SocketStream *accept() = 0;
+    virtual int connect(unsigned short port) = 0;
+
+    virtual void *allocBuffer(size_t minSize);
+    virtual int commitBuffer(size_t size);
+    virtual const unsigned char *readFully(void *buf, size_t len);
+    virtual const unsigned char *read(void *buf, size_t *inout_len);
+
+    bool valid() { return m_sock >= 0; }
+    virtual int recv(void *buf, size_t len);
+    virtual int writeFully(const void *buf, size_t len);
+
+protected:
+    int            m_sock;
+    size_t         m_bufsize;
+    unsigned char *m_buf;
+
+    SocketStream(int sock, size_t bufSize);
+};
+
+#endif /* __SOCKET_STREAM_H */
diff --git a/opengl/shared/OpenglCodecCommon/TcpStream.cpp b/opengl/shared/OpenglCodecCommon/TcpStream.cpp
new file mode 100644
index 0000000..4da2cec
--- /dev/null
+++ b/opengl/shared/OpenglCodecCommon/TcpStream.cpp
@@ -0,0 +1,91 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#include "TcpStream.h"
+#include <cutils/sockets.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#ifndef _WIN32
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#else
+#include <ws2tcpip.h>
+#endif
+
+TcpStream::TcpStream(size_t bufSize) :
+    SocketStream(bufSize)
+{
+}
+
+TcpStream::TcpStream(int sock, size_t bufSize) :
+    SocketStream(sock, bufSize)
+{
+    // disable Nagle algorithm to improve bandwidth of small
+    // packets which are quite common in our implementation.
+#ifdef _WIN32
+    DWORD  flag;
+#else
+    int    flag;
+#endif
+    flag = 1;
+    setsockopt( sock, IPPROTO_TCP, TCP_NODELAY, (const char*)&flag, sizeof(flag) );
+}
+
+int TcpStream::listen(unsigned short port)
+{
+    m_sock = socket_loopback_server(port, SOCK_STREAM);
+    if (!valid()) return int(ERR_INVALID_SOCKET);
+
+    return 0;
+}
+
+SocketStream * TcpStream::accept()
+{
+    int clientSock = -1;
+
+    while (true) {
+        struct sockaddr_in addr;
+        socklen_t len = sizeof(addr);
+        clientSock = ::accept(m_sock, (sockaddr *)&addr, &len);
+
+        if (clientSock < 0 && errno == EINTR) {
+            continue;
+        }
+        break;
+    }
+
+    TcpStream *clientStream = NULL;
+
+    if (clientSock >= 0) {
+        clientStream =  new TcpStream(clientSock, m_bufsize);
+    }
+    return clientStream;
+}
+
+int TcpStream::connect(unsigned short port)
+{
+    return connect("127.0.0.1",port);
+}
+
+int TcpStream::connect(const char* hostname, unsigned short port)
+{
+    m_sock = socket_network_client(hostname, port, SOCK_STREAM);
+    if (!valid()) return -1;
+    return 0;
+}
diff --git a/opengl/shared/OpenglCodecCommon/TcpStream.h b/opengl/shared/OpenglCodecCommon/TcpStream.h
new file mode 100644
index 0000000..811a871
--- /dev/null
+++ b/opengl/shared/OpenglCodecCommon/TcpStream.h
@@ -0,0 +1,32 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#ifndef __TCP_STREAM_H
+#define __TCP_STREAM_H
+
+#include "SocketStream.h"
+
+class TcpStream : public SocketStream {
+public:
+    explicit TcpStream(size_t bufsize = 10000);
+    virtual int listen(unsigned short port);
+    virtual SocketStream *accept();
+    virtual int connect(unsigned short port);
+    int connect(const char* hostname, unsigned short port);
+private:
+    TcpStream(int sock, size_t bufSize);
+};
+
+#endif
diff --git a/opengl/shared/OpenglCodecCommon/TimeUtils.cpp b/opengl/shared/OpenglCodecCommon/TimeUtils.cpp
new file mode 100644
index 0000000..50aeb03
--- /dev/null
+++ b/opengl/shared/OpenglCodecCommon/TimeUtils.cpp
@@ -0,0 +1,69 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#include "TimeUtils.h"
+
+#ifdef _WIN32
+#include <windows.h>
+#include <time.h>
+#include <stdio.h>
+#elif defined(__linux__)
+#include <stdlib.h>
+#include <sys/time.h>
+#include <time.h>
+#include <unistd.h>
+#else
+#include <sys/time.h>
+#include <unistd.h>
+#endif
+
+long long GetCurrentTimeMS()
+{
+#ifdef _WIN32
+    static LARGE_INTEGER freq;
+    static bool bNotInit = true;
+    if ( bNotInit ) {
+        bNotInit = (QueryPerformanceFrequency( &freq ) == FALSE);
+    }
+    LARGE_INTEGER currVal;
+    QueryPerformanceCounter( &currVal );
+
+    return currVal.QuadPart / (freq.QuadPart / 1000);
+
+#elif defined(__linux__)
+
+    struct timespec now;
+    clock_gettime(CLOCK_MONOTONIC, &now);
+    long long iDiff = (now.tv_sec * 1000LL) + now.tv_nsec/1000000LL;
+    return iDiff;
+
+#else /* Others, e.g. OS X */
+
+    struct timeval now;
+    gettimeofday(&now, NULL);
+    long long iDiff = (now.tv_sec * 1000LL) + now.tv_usec/1000LL;
+    return iDiff;
+
+#endif
+}
+
+void TimeSleepMS(int p_mili)
+{
+#ifdef _WIN32
+    Sleep(p_mili);
+#else
+    usleep(p_mili * 1000);
+#endif
+}
diff --git a/opengl/shared/OpenglCodecCommon/TimeUtils.h b/opengl/shared/OpenglCodecCommon/TimeUtils.h
new file mode 100644
index 0000000..bc4fd1c
--- /dev/null
+++ b/opengl/shared/OpenglCodecCommon/TimeUtils.h
@@ -0,0 +1,22 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#ifndef _TIME_UTILS_H
+#define _TIME_UTILS_H
+
+long long GetCurrentTimeMS();
+void TimeSleepMS(int p_mili);
+
+#endif
diff --git a/opengl/shared/OpenglCodecCommon/UnixStream.cpp b/opengl/shared/OpenglCodecCommon/UnixStream.cpp
new file mode 100644
index 0000000..8e463a3
--- /dev/null
+++ b/opengl/shared/OpenglCodecCommon/UnixStream.cpp
@@ -0,0 +1,137 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#include "UnixStream.h"
+#include <cutils/sockets.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <sys/un.h>
+#include <sys/stat.h>
+
+/* Not all systems define PATH_MAX, those who don't generally don't
+ * have a limit on the maximum path size, so use a value that is
+ * large enough for our very limited needs.
+ */
+#ifndef PATH_MAX
+#define PATH_MAX   128
+#endif
+
+UnixStream::UnixStream(size_t bufSize) :
+    SocketStream(bufSize)
+{
+}
+
+UnixStream::UnixStream(int sock, size_t bufSize) :
+    SocketStream(sock, bufSize)
+{
+}
+
+/* Initialize a sockaddr_un with the appropriate values corresponding
+ * to a given 'virtual port'. Returns 0 on success, -1 on error.
+ */
+static int
+make_unix_path(char *path, size_t  pathlen, int port_number)
+{
+    char  tmp[PATH_MAX];  // temp directory
+    int   ret = 0;
+
+    // First, create user-specific temp directory if needed
+    const char* user = getenv("USER");
+    if (user != NULL) {
+        struct stat  st;
+        snprintf(tmp, sizeof(tmp), "/tmp/android-%s", user);
+        do {
+            ret = ::lstat(tmp, &st);
+        } while (ret < 0 && errno == EINTR);
+
+        if (ret < 0 && errno == ENOENT) {
+            do {
+                ret = ::mkdir(tmp, 0766);
+            } while (ret < 0 && errno == EINTR);
+            if (ret < 0) {
+                ERR("Could not create temp directory: %s", tmp);
+                user = NULL;  // will fall-back to /tmp
+            }
+        }
+        else if (ret < 0) {
+            user = NULL;  // will fallback to /tmp
+        }
+    }
+
+    if (user == NULL) {  // fallback to /tmp in case of error
+        snprintf(tmp, sizeof(tmp), "/tmp");
+    }
+
+    // Now, initialize it properly
+    snprintf(path, pathlen, "%s/qemu-gles-%d", tmp, port_number);
+    return 0;
+}
+
+
+int UnixStream::listen(unsigned short port)
+{
+    char  path[PATH_MAX];
+
+    if (make_unix_path(path, sizeof(path), port) < 0) {
+        return -1;
+    }
+
+    m_sock = socket_local_server(path, ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM);
+    if (!valid()) return int(ERR_INVALID_SOCKET);
+
+    return 0;
+}
+
+SocketStream * UnixStream::accept()
+{
+    int clientSock = -1;
+
+    while (true) {
+        struct sockaddr_un addr;
+        socklen_t len = sizeof(addr);
+        clientSock = ::accept(m_sock, (sockaddr *)&addr, &len);
+
+        if (clientSock < 0 && errno == EINTR) {
+            continue;
+        }
+        break;
+    }
+
+    UnixStream *clientStream = NULL;
+
+    if (clientSock >= 0) {
+        clientStream =  new UnixStream(clientSock, m_bufsize);
+    }
+    return clientStream;
+}
+
+int UnixStream::connect(unsigned short port)
+{
+    char  path[PATH_MAX];
+
+    if (make_unix_path(path, sizeof(path), port) < 0)
+        return -1;
+
+    m_sock = socket_local_client(path, ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM);
+    if (!valid()) return -1;
+
+    return 0;
+}
diff --git a/opengl/shared/OpenglCodecCommon/UnixStream.h b/opengl/shared/OpenglCodecCommon/UnixStream.h
new file mode 100644
index 0000000..c184b19
--- /dev/null
+++ b/opengl/shared/OpenglCodecCommon/UnixStream.h
@@ -0,0 +1,31 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#ifndef __UNIX_STREAM_H
+#define __UNIX_STREAM_H
+
+#include "SocketStream.h"
+
+class UnixStream : public SocketStream {
+public:
+    explicit UnixStream(size_t bufsize = 10000);
+    virtual int listen(unsigned short port);
+    virtual SocketStream *accept();
+    virtual int connect(unsigned short port);
+private:
+    UnixStream(int sock, size_t bufSize);
+};
+
+#endif
diff --git a/opengl/shared/OpenglCodecCommon/Win32PipeStream.cpp b/opengl/shared/OpenglCodecCommon/Win32PipeStream.cpp
new file mode 100644
index 0000000..e1a0b9b
--- /dev/null
+++ b/opengl/shared/OpenglCodecCommon/Win32PipeStream.cpp
@@ -0,0 +1,239 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#include "Win32PipeStream.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <windows.h>
+
+#ifndef _WIN32
+#error ONLY BUILD THIS SOURCE FILE FOR WINDOWS!
+#endif
+
+/* The official documentation states that the name of a given named
+ * pipe cannot be more than 256 characters long.
+ */
+#define NAMED_PIPE_MAX 256
+
+Win32PipeStream::Win32PipeStream(size_t bufSize) :
+    SocketStream(bufSize),
+    m_pipe(INVALID_HANDLE_VALUE)
+{
+}
+
+Win32PipeStream::Win32PipeStream(HANDLE pipe, size_t bufSize) :
+    SocketStream(-1, bufSize),
+    m_pipe(pipe)
+{
+}
+
+Win32PipeStream::~Win32PipeStream()
+{
+    if (m_pipe != INVALID_HANDLE_VALUE) {
+        CloseHandle(m_pipe);
+        m_pipe = INVALID_HANDLE_VALUE;
+    }
+}
+
+/* Initialize the pipe name corresponding to a given port
+ */
+static void
+make_pipe_name(char *path, size_t  pathlen, int port_number)
+{
+    snprintf(path, pathlen, "\\\\.\\pipe\\qemu-gles-%d", port_number);
+}
+
+
+/* Technical note: Named pipes work differently from BSD Sockets.
+ * One does not create/bind a pipe, and collect a new handle each
+ * time a client connects with accept().
+ *
+ * Instead, the server creates a new pipe instance each time it wants
+ * to get a new client connection, then calls ConnectNamedPipe() to
+ * wait for a connection.
+ *
+ * So listen() is a no-op, and accept() really creates the pipe handle.
+ *
+ * Also, connect() must create a pipe handle with CreateFile() and
+ * wait for a server instance with WaitNamedPipe()
+ */
+int Win32PipeStream::listen(unsigned short port)
+{
+    // just save the port number for accept()
+    m_port = port;
+    return 0;
+}
+
+SocketStream * Win32PipeStream::accept()
+{
+    char path[NAMED_PIPE_MAX+1];
+    SocketStream*  clientStream;
+    HANDLE pipe;
+
+    make_pipe_name(path, sizeof(path), m_port);
+
+    pipe = ::CreateNamedPipe(
+                path,                // pipe name
+                PIPE_ACCESS_DUPLEX,  // read-write access
+                PIPE_TYPE_BYTE |     // byte-oriented writes
+                PIPE_READMODE_BYTE | // byte-oriented reads
+                PIPE_WAIT,           // blocking operations
+                PIPE_UNLIMITED_INSTANCES, // no limit on clients
+                4096,                // input buffer size
+                4096,                // output buffer size
+                0,                   // client time-out
+                NULL);               // default security attributes
+
+    if (pipe == INVALID_HANDLE_VALUE) {
+        ERR("%s: CreateNamedPipe failed %d\n", __FUNCTION__, (int)GetLastError());
+        return NULL;
+    }
+
+    // Stupid Win32 API design: If a client is already connected, then
+    // ConnectNamedPipe will return 0, and GetLastError() will return
+    // ERROR_PIPE_CONNECTED. This is not an error! It just means that the
+    // function didn't have to wait.
+    //
+    if (::ConnectNamedPipe(pipe, NULL) == 0 && GetLastError() != ERROR_PIPE_CONNECTED) {
+        ERR("%s: ConnectNamedPipe failed: %d\n", __FUNCTION__, (int)GetLastError());
+        CloseHandle(pipe);
+        return NULL;
+    }
+
+    clientStream = new Win32PipeStream(pipe, m_bufsize);
+    return clientStream;
+}
+
+int Win32PipeStream::connect(unsigned short port)
+{
+    char   path[NAMED_PIPE_MAX+1];
+    HANDLE pipe;
+    int    tries = 10;
+
+    make_pipe_name(path, sizeof(path), port);
+
+    /* We're going to loop in order to wait for the pipe server to
+     * be setup properly.
+     */
+    for (; tries > 0; tries--) {
+        pipe = ::CreateFile(
+                    path,                          // pipe name
+                    GENERIC_READ | GENERIC_WRITE,  // read & write
+                    0,                             // no sharing
+                    NULL,                          // default security attrs
+                    OPEN_EXISTING,                 // open existing pipe
+                    0,                             // default attributes
+                    NULL);                         // no template file
+
+        /* If we have a valid pipe handle, break from the loop */
+        if (pipe != INVALID_HANDLE_VALUE) {
+            break;
+        }
+
+        /* We can get here if the pipe is busy, i.e. if the server hasn't
+         * create a new pipe instance to service our request. In which case
+         * GetLastError() will return ERROR_PIPE_BUSY.
+         *
+         * If so, then use WaitNamedPipe() to wait for a decent time
+         * to try again.
+         */
+        if (GetLastError() != ERROR_PIPE_BUSY) {
+            /* Not ERROR_PIPE_BUSY */
+            ERR("%s: CreateFile failed: %d\n", __FUNCTION__, (int)GetLastError());
+            errno = EINVAL;
+            return -1;
+        }
+
+        /* Wait for 5 seconds */
+        if ( !WaitNamedPipe(path, 5000) ) {
+            ERR("%s: WaitNamedPipe failed: %d\n", __FUNCTION__, (int)GetLastError());
+            errno = EINVAL;
+            return -1;
+        }
+    }
+
+    m_pipe = pipe;
+    return 0;
+}
+
+/* Special buffer methods, since we can't use socket functions here */
+
+int Win32PipeStream::commitBuffer(size_t size)
+{
+    if (m_pipe == INVALID_HANDLE_VALUE)
+        return -1;
+
+    size_t res = size;
+    int retval = 0;
+
+    while (res > 0) {
+        DWORD  written;
+        if (! ::WriteFile(m_pipe, (const char *)m_buf + (size - res), res, &written, NULL)) {
+            retval =  -1;
+            ERR("%s: failed: %d\n", __FUNCTION__, (int)GetLastError());
+            break;
+        }
+        res -= written;
+    }
+    return retval;
+}
+
+const unsigned char *Win32PipeStream::readFully(void *buf, size_t len)
+{
+    const unsigned char* ret = NULL;
+
+    if (m_pipe == INVALID_HANDLE_VALUE)
+        return NULL;
+
+    if (!buf) {
+        return NULL;  // do not allow NULL buf in that implementation
+    }
+
+    size_t res = len;
+    while (res > 0) {
+        DWORD  readcount = 0;
+        if (! ::ReadFile(m_pipe, (char *)buf + (len - res), res, &readcount, NULL) || readcount == 0) {
+            errno = (int)GetLastError();
+            return NULL;
+        }
+        res -= readcount;
+    }
+    return (const unsigned char *)buf;
+}
+
+const unsigned char *Win32PipeStream::read( void *buf, size_t *inout_len)
+{
+    size_t len = *inout_len;
+    DWORD  readcount;
+
+    if (m_pipe == INVALID_HANDLE_VALUE)
+        return NULL;
+
+    if (!buf) {
+        return NULL;  // do not allow NULL buf in that implementation
+    }
+
+    if (!::ReadFile(m_pipe, (char *)buf, len, &readcount, NULL)) {
+        errno = (int)GetLastError();
+        return NULL;
+    }
+
+    *inout_len = (size_t)readcount;
+    return (const unsigned char *)buf;
+}
diff --git a/opengl/shared/OpenglCodecCommon/Win32PipeStream.h b/opengl/shared/OpenglCodecCommon/Win32PipeStream.h
new file mode 100644
index 0000000..4114545
--- /dev/null
+++ b/opengl/shared/OpenglCodecCommon/Win32PipeStream.h
@@ -0,0 +1,41 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#ifndef __WIN32_PIPE_STREAM_H
+#define __WIN32_PIPE_STREAM_H
+
+#include "SocketStream.h"
+#include <windows.h>
+
+class Win32PipeStream : public SocketStream {
+public:
+    explicit Win32PipeStream(size_t bufsize = 10000);
+    virtual ~Win32PipeStream();
+    virtual int listen(unsigned short port);
+    virtual SocketStream *accept();
+    virtual int connect(unsigned short port);
+
+    virtual int commitBuffer(size_t size);
+    virtual const unsigned char *readFully(void *buf, size_t len);
+    virtual const unsigned char *read(void *buf, size_t *inout_len);
+
+private:
+    Win32PipeStream(HANDLE pipe, size_t bufSize);
+    HANDLE  m_pipe;
+    int     m_port;
+};
+
+
+#endif
diff --git a/opengl/shared/OpenglCodecCommon/codec_defs.h b/opengl/shared/OpenglCodecCommon/codec_defs.h
new file mode 100644
index 0000000..f19f514
--- /dev/null
+++ b/opengl/shared/OpenglCodecCommon/codec_defs.h
@@ -0,0 +1,23 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#ifndef _CODEC_DEFS_H
+#define _CODEC_DEFS_H
+
+#define CODEC_SERVER_PORT 22468
+
+#define CODEC_MAX_VERTEX_ATTRIBUTES 64
+
+#endif
diff --git a/opengl/shared/OpenglCodecCommon/glUtils.cpp b/opengl/shared/OpenglCodecCommon/glUtils.cpp
new file mode 100644
index 0000000..4b7fc89
--- /dev/null
+++ b/opengl/shared/OpenglCodecCommon/glUtils.cpp
@@ -0,0 +1,471 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#include "glUtils.h"
+#include <string.h>
+#include "ErrorLog.h"
+#include <IOStream.h>
+
+size_t glSizeof(GLenum type)
+{
+    size_t retval = 0;
+    switch(type) {
+    case GL_BYTE:
+    case GL_UNSIGNED_BYTE:
+        retval = 1;
+        break;
+    case GL_SHORT:
+    case GL_UNSIGNED_SHORT:
+    case GL_HALF_FLOAT_OES:
+        retval = 2;
+        break;
+    case GL_INT:
+    case GL_FLOAT:
+    case GL_FIXED:
+    case GL_BOOL:
+        retval =  4;
+        break;
+#ifdef GL_DOUBLE
+    case GL_DOUBLE:
+        retval = 8;
+        break;
+#endif
+    case GL_FLOAT_VEC2:
+    case GL_INT_VEC2:
+    case GL_BOOL_VEC2:
+        retval = 8;
+        break;
+    case GL_INT_VEC3:
+    case GL_BOOL_VEC3:
+    case GL_FLOAT_VEC3:
+        retval = 12;
+        break;
+    case GL_FLOAT_VEC4:
+    case GL_BOOL_VEC4:
+    case GL_INT_VEC4:
+    case GL_FLOAT_MAT2:
+        retval = 16;
+        break;
+    case GL_FLOAT_MAT3:
+        retval = 36;
+        break;
+    case GL_FLOAT_MAT4:
+        retval = 64;
+        break;
+    case GL_SAMPLER_2D:
+    case GL_SAMPLER_CUBE:
+        retval = 4;
+        break;
+    default:
+        ERR("**** ERROR unknown type 0x%x (%s,%d)\n", type, __FUNCTION__,__LINE__);
+    }
+    return retval;
+
+}
+
+size_t glUtilsParamSize(GLenum param)
+{
+    size_t s = 0;
+
+    switch(param)
+    {
+    case GL_DEPTH_TEST:
+    case GL_DEPTH_FUNC:
+    case GL_DEPTH_BITS:
+    case GL_MAX_CLIP_PLANES:
+    case GL_GREEN_BITS:
+    case GL_MAX_MODELVIEW_STACK_DEPTH:
+    case GL_MAX_PROJECTION_STACK_DEPTH:
+    case GL_MAX_TEXTURE_STACK_DEPTH:
+    case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
+    case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
+    case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
+    case GL_MAX_TEXTURE_SIZE:
+    case GL_TEXTURE_GEN_MODE_OES:
+    case GL_TEXTURE_ENV_MODE:
+    case GL_FOG_MODE:
+    case GL_FOG_DENSITY:
+    case GL_FOG_START:
+    case GL_FOG_END:
+    case GL_SPOT_EXPONENT:
+    case GL_CONSTANT_ATTENUATION:
+    case GL_LINEAR_ATTENUATION:
+    case GL_QUADRATIC_ATTENUATION:
+    case GL_SHININESS:
+    case GL_LIGHT_MODEL_TWO_SIDE:
+    case GL_POINT_SIZE:
+    case GL_POINT_SIZE_MIN:
+    case GL_POINT_SIZE_MAX:
+    case GL_POINT_FADE_THRESHOLD_SIZE:
+    case GL_CULL_FACE_MODE:
+    case GL_FRONT_FACE:
+    case GL_SHADE_MODEL:
+    case GL_DEPTH_WRITEMASK:
+    case GL_DEPTH_CLEAR_VALUE:
+    case GL_STENCIL_FAIL:
+    case GL_STENCIL_PASS_DEPTH_FAIL:
+    case GL_STENCIL_PASS_DEPTH_PASS:
+    case GL_STENCIL_REF:
+    case GL_STENCIL_WRITEMASK:
+    case GL_MATRIX_MODE:
+    case GL_MODELVIEW_STACK_DEPTH:
+    case GL_PROJECTION_STACK_DEPTH:
+    case GL_TEXTURE_STACK_DEPTH:
+    case GL_ALPHA_TEST_FUNC:
+    case GL_ALPHA_TEST_REF:
+    case GL_ALPHA_TEST:
+    case GL_BLEND_DST:
+    case GL_BLEND_SRC:
+    case GL_BLEND:
+    case GL_LOGIC_OP_MODE:
+    case GL_SCISSOR_TEST:
+    case GL_MAX_TEXTURE_UNITS:
+    case GL_ACTIVE_TEXTURE:
+    case GL_ALPHA_BITS:
+    case GL_ARRAY_BUFFER_BINDING:
+    case GL_BLUE_BITS:
+    case GL_CLIENT_ACTIVE_TEXTURE:
+    case GL_CLIP_PLANE0:
+    case GL_CLIP_PLANE1:
+    case GL_CLIP_PLANE2:
+    case GL_CLIP_PLANE3:
+    case GL_CLIP_PLANE4:
+    case GL_CLIP_PLANE5:
+    case GL_COLOR_ARRAY:
+    case GL_COLOR_ARRAY_BUFFER_BINDING:
+    case GL_COLOR_ARRAY_SIZE:
+    case GL_COLOR_ARRAY_STRIDE:
+    case GL_COLOR_ARRAY_TYPE:
+    case GL_COLOR_LOGIC_OP:
+    case GL_COLOR_MATERIAL:
+    case GL_PACK_ALIGNMENT:
+    case GL_PERSPECTIVE_CORRECTION_HINT:
+    case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
+    case GL_POINT_SIZE_ARRAY_STRIDE_OES:
+    case GL_POINT_SIZE_ARRAY_TYPE_OES:
+    case GL_POINT_SMOOTH:
+    case GL_POINT_SMOOTH_HINT:
+    case GL_POINT_SPRITE_OES:
+    case GL_COORD_REPLACE_OES:
+    case GL_COMBINE_ALPHA:
+    case GL_SRC0_RGB:
+    case GL_SRC1_RGB:
+    case GL_SRC2_RGB:
+    case GL_OPERAND0_RGB:
+    case GL_OPERAND1_RGB:
+    case GL_OPERAND2_RGB:
+    case GL_SRC0_ALPHA:
+    case GL_SRC1_ALPHA:
+    case GL_SRC2_ALPHA:
+    case GL_OPERAND0_ALPHA:
+    case GL_OPERAND1_ALPHA:
+    case GL_OPERAND2_ALPHA:
+    case GL_RGB_SCALE:
+    case GL_ALPHA_SCALE:
+    case GL_COMBINE_RGB:
+    case GL_POLYGON_OFFSET_FACTOR:
+    case GL_POLYGON_OFFSET_FILL:
+    case GL_POLYGON_OFFSET_UNITS:
+    case GL_RED_BITS:
+    case GL_RESCALE_NORMAL:
+    case GL_SAMPLE_ALPHA_TO_COVERAGE:
+    case GL_SAMPLE_ALPHA_TO_ONE:
+    case GL_SAMPLE_BUFFERS:
+    case GL_SAMPLE_COVERAGE:
+    case GL_SAMPLE_COVERAGE_INVERT:
+    case GL_SAMPLE_COVERAGE_VALUE:
+    case GL_SAMPLES:
+    case GL_STENCIL_BITS:
+    case GL_STENCIL_CLEAR_VALUE:
+    case GL_STENCIL_FUNC:
+    case GL_STENCIL_TEST:
+    case GL_STENCIL_VALUE_MASK:
+    case GL_STENCIL_BACK_FUNC:
+    case GL_STENCIL_BACK_VALUE_MASK:
+    case GL_STENCIL_BACK_REF:
+    case GL_STENCIL_BACK_FAIL:
+    case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
+    case GL_STENCIL_BACK_PASS_DEPTH_PASS:
+    case GL_STENCIL_BACK_WRITEMASK:
+    case GL_TEXTURE_2D:
+    case GL_TEXTURE_BINDING_2D:
+    case GL_TEXTURE_BINDING_CUBE_MAP:
+    case GL_TEXTURE_BINDING_EXTERNAL_OES:
+    case GL_TEXTURE_COORD_ARRAY:
+    case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:
+    case GL_TEXTURE_COORD_ARRAY_SIZE:
+    case GL_TEXTURE_COORD_ARRAY_STRIDE:
+    case GL_TEXTURE_COORD_ARRAY_TYPE:
+    case GL_UNPACK_ALIGNMENT:
+    case GL_VERTEX_ARRAY:
+    case GL_VERTEX_ARRAY_BUFFER_BINDING:
+    case GL_VERTEX_ARRAY_SIZE:
+    case GL_VERTEX_ARRAY_STRIDE:
+    case GL_VERTEX_ARRAY_TYPE:
+    case GL_SPOT_CUTOFF:
+    case GL_TEXTURE_MIN_FILTER:
+    case GL_TEXTURE_MAG_FILTER:
+    case GL_TEXTURE_WRAP_S:
+    case GL_TEXTURE_WRAP_T:
+    case GL_GENERATE_MIPMAP:
+    case GL_GENERATE_MIPMAP_HINT:
+    case GL_RENDERBUFFER_WIDTH_OES:
+    case GL_RENDERBUFFER_HEIGHT_OES:
+    case GL_RENDERBUFFER_INTERNAL_FORMAT_OES:
+    case GL_RENDERBUFFER_RED_SIZE_OES:
+    case GL_RENDERBUFFER_GREEN_SIZE_OES:
+    case GL_RENDERBUFFER_BLUE_SIZE_OES:
+    case GL_RENDERBUFFER_ALPHA_SIZE_OES:
+    case GL_RENDERBUFFER_DEPTH_SIZE_OES:
+    case GL_RENDERBUFFER_STENCIL_SIZE_OES:
+    case GL_RENDERBUFFER_BINDING:
+    case GL_FRAMEBUFFER_BINDING:
+    case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_OES:
+    case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_OES:
+    case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_OES:
+    case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_OES:
+    case GL_FENCE_STATUS_NV:
+    case GL_FENCE_CONDITION_NV:
+    case GL_TEXTURE_WIDTH_QCOM:
+    case GL_TEXTURE_HEIGHT_QCOM:
+    case GL_TEXTURE_DEPTH_QCOM:
+    case GL_TEXTURE_INTERNAL_FORMAT_QCOM:
+    case GL_TEXTURE_FORMAT_QCOM:
+    case GL_TEXTURE_TYPE_QCOM:
+    case GL_TEXTURE_IMAGE_VALID_QCOM:
+    case GL_TEXTURE_NUM_LEVELS_QCOM:
+    case GL_TEXTURE_TARGET_QCOM:
+    case GL_TEXTURE_OBJECT_VALID_QCOM:
+    case GL_BLEND_EQUATION_RGB_OES:
+    case GL_BLEND_EQUATION_ALPHA_OES:
+    case GL_BLEND_DST_RGB_OES:
+    case GL_BLEND_SRC_RGB_OES:
+    case GL_BLEND_DST_ALPHA_OES:
+    case GL_BLEND_SRC_ALPHA_OES:
+    case GL_MAX_LIGHTS:
+    case GL_SHADER_TYPE:
+    case GL_DELETE_STATUS:
+    case GL_COMPILE_STATUS:
+    case GL_INFO_LOG_LENGTH:
+    case GL_SHADER_SOURCE_LENGTH:
+    case GL_CURRENT_PROGRAM:
+    case GL_LINK_STATUS:
+    case GL_VALIDATE_STATUS:
+    case GL_ATTACHED_SHADERS:
+    case GL_ACTIVE_UNIFORMS:
+    case GL_ACTIVE_ATTRIBUTES:
+    case GL_SUBPIXEL_BITS:
+    case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
+    case GL_NUM_SHADER_BINARY_FORMATS:
+    case GL_SHADER_COMPILER:
+    case GL_MAX_VERTEX_ATTRIBS:
+    case GL_MAX_VERTEX_UNIFORM_VECTORS:
+    case GL_MAX_VARYING_VECTORS:
+    case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
+    case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
+    case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
+    case GL_MAX_RENDERBUFFER_SIZE:
+    case GL_MAX_TEXTURE_IMAGE_UNITS:
+    case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
+    case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
+    case GL_LINE_WIDTH:
+        s = 1;
+        break;
+    case GL_ALIASED_LINE_WIDTH_RANGE:
+    case GL_ALIASED_POINT_SIZE_RANGE:
+    case GL_DEPTH_RANGE:
+    case GL_MAX_VIEWPORT_DIMS:
+    case GL_SMOOTH_POINT_SIZE_RANGE:
+    case GL_SMOOTH_LINE_WIDTH_RANGE:
+        s= 2;
+        break;
+    case GL_SPOT_DIRECTION:
+    case GL_POINT_DISTANCE_ATTENUATION:
+    case GL_CURRENT_NORMAL:
+        s =  3;
+        break;
+    case GL_CURRENT_VERTEX_ATTRIB:
+    case GL_CURRENT_TEXTURE_COORDS:
+    case GL_CURRENT_COLOR:
+    case GL_FOG_COLOR:
+    case GL_AMBIENT:
+    case GL_DIFFUSE:
+    case GL_SPECULAR:
+    case GL_EMISSION:
+    case GL_POSITION:
+    case GL_LIGHT_MODEL_AMBIENT:
+    case GL_TEXTURE_ENV_COLOR:
+    case GL_SCISSOR_BOX:
+    case GL_VIEWPORT:
+    case GL_TEXTURE_CROP_RECT_OES:
+    case GL_COLOR_CLEAR_VALUE:
+    case GL_COLOR_WRITEMASK:
+    case GL_AMBIENT_AND_DIFFUSE:
+    case GL_BLEND_COLOR:
+        s =  4;
+        break;
+    case GL_MODELVIEW_MATRIX:
+    case GL_PROJECTION_MATRIX:
+    case GL_TEXTURE_MATRIX:
+        s = 16;
+    break;
+    default:
+        ERR("glUtilsParamSize: unknow param 0x%08x\n", param);
+        s = 1; // assume 1
+    }
+    return s;
+}
+
+void glUtilsPackPointerData(unsigned char *dst, unsigned char *src,
+                     int size, GLenum type, unsigned int stride,
+                     unsigned int datalen)
+{
+    unsigned int  vsize = size * glSizeof(type);
+    if (stride == 0) stride = vsize;
+
+    if (stride == vsize) {
+        memcpy(dst, src, datalen);
+    } else {
+        for (unsigned int i = 0; i < datalen; i += vsize) {
+            memcpy(dst, src, vsize);
+            dst += vsize;
+            src += stride;
+        }
+    }
+}
+
+void glUtilsWritePackPointerData(void* _stream, unsigned char *src,
+                                 int size, GLenum type, unsigned int stride,
+                                 unsigned int datalen)
+{
+    IOStream* stream = reinterpret_cast<IOStream*>(_stream);
+
+    unsigned int  vsize = size * glSizeof(type);
+    if (stride == 0) stride = vsize;
+
+    if (stride == vsize) {
+        stream->writeFully(src, datalen);
+    } else {
+        for (unsigned int i = 0; i < datalen; i += vsize) {
+            stream->writeFully(src, (size_t)vsize);
+            src += stride;
+        }
+    }
+}
+
+int glUtilsPixelBitSize(GLenum format, GLenum type)
+{
+    int components = 0;
+    int componentsize = 0;
+    int pixelsize = 0;
+    switch(type) {
+    case GL_BYTE:
+    case GL_UNSIGNED_BYTE:
+        componentsize = 8;
+        break;
+    case GL_SHORT:
+    case GL_UNSIGNED_SHORT:
+    case GL_UNSIGNED_SHORT_5_6_5:
+    case GL_UNSIGNED_SHORT_4_4_4_4:
+    case GL_UNSIGNED_SHORT_5_5_5_1:
+    case GL_RGB565_OES:
+    case GL_RGB5_A1_OES:
+    case GL_RGBA4_OES:
+        pixelsize = 16;
+        break;
+    case GL_INT:
+    case GL_UNSIGNED_INT:
+    case GL_FLOAT:
+    case GL_FIXED:
+    case GL_UNSIGNED_INT_24_8_OES:
+        pixelsize = 32;
+        break;
+    default:
+        ERR("glUtilsPixelBitSize: unknown pixel type - assuming pixel data 0\n");
+        componentsize = 0;
+    }
+
+    if (pixelsize == 0) {
+        switch(format) {
+#if 0
+        case GL_RED:
+        case GL_GREEN:
+        case GL_BLUE:
+#endif
+        case GL_ALPHA:
+        case GL_LUMINANCE:
+        case GL_DEPTH_COMPONENT:
+        case GL_DEPTH_STENCIL_OES:
+            components = 1;
+            break;
+        case GL_LUMINANCE_ALPHA:
+            components = 2;
+            break;
+        case GL_RGB:
+#if 0
+        case GL_BGR:
+#endif
+            components = 3;
+            break;
+        case GL_RGBA:
+        case GL_BGRA_EXT:
+            components = 4;
+            break;
+        default:
+            ERR("glUtilsPixelBitSize: unknown pixel format...\n");
+            components = 0;
+        }
+        pixelsize = components * componentsize;
+    }
+
+    return pixelsize;
+}
+
+// pack a list of strings into one.
+void glUtilsPackStrings(char *ptr,  char **strings,  GLint *length, GLsizei count)
+{
+    char *p = ptr;
+    *p = '\0';
+    for (int i = 0; i < count; i++) {
+        int l=0;
+        if (strings[i]!=NULL) {
+            if (length == NULL || length[i] < 0) {
+                l = strlen(strings[i]);
+                strcat(p, strings[i]);
+            } else {
+                l = length[i];
+                strncat(p, strings[i], l);
+            }
+        }
+        p += l;
+    }
+}
+
+// claculate the length of a list of strings
+int glUtilsCalcShaderSourceLen( char **strings,  GLint *length, GLsizei count)
+{
+    int len = 0;
+    for (int i = 0; i < count; i++) {
+        int l;
+        if (length == NULL || length[i] < 0) {
+            l = strings[i]!=NULL ? strlen(strings[i]) : 0;
+        } else {
+            l = length[i];
+        }
+        len += l;
+    }
+    return len;
+
+}
diff --git a/opengl/shared/OpenglCodecCommon/glUtils.h b/opengl/shared/OpenglCodecCommon/glUtils.h
new file mode 100644
index 0000000..f8857f1
--- /dev/null
+++ b/opengl/shared/OpenglCodecCommon/glUtils.h
@@ -0,0 +1,95 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#ifndef __GL_UTILS_H__
+#define __GL_UTILS_H__
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef GL_API
+    #undef GL_API
+#endif
+#define GL_API
+
+#ifdef GL_APIENTRY
+    #undef GL_APIENTRY
+#endif
+
+#ifdef GL_APIENTRYP
+    #undef GL_APIENTRYP
+#endif
+#define GL_APIENTRYP
+
+#ifndef ANDROID
+#define GL_APIENTRY
+#endif
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+    size_t glSizeof(GLenum type);
+    size_t glUtilsParamSize(GLenum param);
+    void   glUtilsPackPointerData(unsigned char *dst, unsigned char *str,
+                           int size, GLenum type, unsigned int stride,
+                           unsigned int datalen);
+    void glUtilsWritePackPointerData(void* stream, unsigned char *src,
+                                    int size, GLenum type, unsigned int stride,
+                                    unsigned int datalen);
+    int glUtilsPixelBitSize(GLenum format, GLenum type);
+    void   glUtilsPackStrings(char *ptr, char **strings, GLint *length, GLsizei count);
+    int glUtilsCalcShaderSourceLen(char **strings, GLint *length, GLsizei count);
+#ifdef __cplusplus
+};
+#endif
+
+namespace GLUtils {
+
+    template <class T> void minmax(T *indices, int count, int *min, int *max) {
+        *min = -1;
+        *max = -1;
+        T *ptr = indices;
+        for (int i = 0; i < count; i++) {
+            if (*min == -1 || *ptr < *min) *min = *ptr;
+            if (*max == -1 || *ptr > *max) *max = *ptr;
+            ptr++;
+        }
+    }
+
+    template <class T> void shiftIndices(T *indices, int count,  int offset) {
+        T *ptr = indices;
+        for (int i = 0; i < count; i++) {
+            *ptr += offset;
+            ptr++;
+        }
+    }
+
+
+    template <class T> void shiftIndices(T *src, T *dst, int count, int offset)
+    {
+        for (int i = 0; i < count; i++) {
+            *dst = *src + offset;
+            dst++;
+            src++;
+        }
+    }
+}; // namespace GLUtils
+#endif
diff --git a/opengl/shared/OpenglCodecCommon/gl_base_types.h b/opengl/shared/OpenglCodecCommon/gl_base_types.h
new file mode 100644
index 0000000..d7bdef8
--- /dev/null
+++ b/opengl/shared/OpenglCodecCommon/gl_base_types.h
@@ -0,0 +1,62 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#ifndef __GL_BASE_TYPES__H
+#define __GL_BASE_TYPES__H
+
+#include <KHR/khrplatform.h>
+
+#ifndef gl_APIENTRY
+#define gl_APIENTRY KHRONOS_APIENTRY
+#endif
+
+#ifndef gl2_APIENTRY
+#define gl2_APIENTRY KHRONOS_APIENTRY
+#endif
+
+typedef void             GLvoid;
+typedef unsigned int     GLenum;
+typedef unsigned char    GLboolean;
+typedef unsigned int     GLbitfield;
+typedef char             GLchar;
+typedef khronos_int8_t   GLbyte;
+typedef short            GLshort;
+typedef int              GLint;
+typedef int              GLsizei;
+typedef khronos_uint8_t  GLubyte;
+typedef unsigned short   GLushort;
+typedef unsigned int     GLuint;
+typedef khronos_float_t  GLfloat;
+typedef khronos_float_t  GLclampf;
+typedef khronos_int32_t  GLfixed;
+typedef khronos_int32_t  GLclampx;
+typedef khronos_intptr_t GLintptr;
+typedef khronos_ssize_t  GLsizeiptr;
+typedef char *GLstr;
+/* JR XXX Treating this as an in handle - is this correct? */
+typedef void * GLeglImageOES;
+
+/* ErrorCode */
+#ifndef GL_INVALID_ENUM
+#define GL_NO_ERROR                       0
+#define GL_INVALID_ENUM                   0x0500
+#define GL_INVALID_VALUE                  0x0501
+#define GL_INVALID_OPERATION              0x0502
+#define GL_STACK_OVERFLOW                 0x0503
+#define GL_STACK_UNDERFLOW                0x0504
+#define GL_OUT_OF_MEMORY                  0x0505
+#endif
+
+#endif
diff --git a/opengl/shared/OpenglOsUtils/Android.mk b/opengl/shared/OpenglOsUtils/Android.mk
new file mode 100644
index 0000000..e7fd9e9
--- /dev/null
+++ b/opengl/shared/OpenglOsUtils/Android.mk
@@ -0,0 +1,20 @@
+# This build script corresponds to a small library containing
+# OS-specific support functions for:
+#   - thread-local storage
+#   - dynamic library loading
+#   - child process creation and wait  (probably not needed in guest)
+#
+LOCAL_PATH := $(call my-dir)
+
+### Guest library ##############################################
+$(call emugl-begin-static-library,libOpenglOsUtils)
+
+    $(call emugl-export,C_INCLUDES,$(LOCAL_PATH))
+    $(call emugl-export,LDLIBS,-ldl)
+
+    LOCAL_SRC_FILES := \
+        osProcessUnix.cpp \
+        osThreadUnix.cpp \
+        osDynLibrary.cpp
+
+$(call emugl-end-module)
diff --git a/opengl/shared/OpenglOsUtils/osDynLibrary.cpp b/opengl/shared/OpenglOsUtils/osDynLibrary.cpp
new file mode 100644
index 0000000..e8e6ab7
--- /dev/null
+++ b/opengl/shared/OpenglOsUtils/osDynLibrary.cpp
@@ -0,0 +1,79 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#include "osDynLibrary.h"
+
+#ifndef _WIN32
+#include <dlfcn.h>
+#endif
+#include <stdio.h>
+
+namespace osUtils {
+
+dynLibrary *dynLibrary::open(const char *p_libName)
+{
+    dynLibrary *lib = new dynLibrary();
+    if (!lib) {
+        return NULL;
+    }
+
+#ifdef _WIN32
+    lib->m_lib = LoadLibrary(p_libName);
+#else // !WIN32
+    lib->m_lib = dlopen(p_libName, RTLD_NOW);
+#endif
+
+    if (lib->m_lib == NULL) {
+        printf("Failed to load %s\n", p_libName);
+#ifndef _WIN32
+        printf("error %s\n", dlerror()); //only on linux
+#endif
+        delete lib;
+        return NULL;
+    }
+
+    return lib;
+}
+
+dynLibrary::dynLibrary() :
+    m_lib(NULL)
+{
+}
+
+dynLibrary::~dynLibrary()
+{
+    if (NULL != m_lib) {
+#ifdef _WIN32
+        FreeLibrary(m_lib);
+#else // !WIN32
+        dlclose(m_lib);
+#endif
+    }
+}
+
+dynFuncPtr dynLibrary::findSymbol(const char *p_symName)
+{
+    if (NULL == m_lib) {
+        return NULL;
+    }
+
+#ifdef _WIN32
+    return (dynFuncPtr) GetProcAddress(m_lib, p_symName);
+#else // !WIN32
+    return (dynFuncPtr) dlsym(m_lib, p_symName);
+#endif
+}
+
+} // of namespace osUtils
diff --git a/opengl/shared/OpenglOsUtils/osDynLibrary.h b/opengl/shared/OpenglOsUtils/osDynLibrary.h
new file mode 100644
index 0000000..c83fbf3
--- /dev/null
+++ b/opengl/shared/OpenglOsUtils/osDynLibrary.h
@@ -0,0 +1,71 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#ifndef _OSUTILS_DYN_LIBRARY_H
+#define _OSUTILS_DYN_LIBRARY_H
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+namespace osUtils {
+
+typedef void (*dynFuncPtr)(void);
+
+class dynLibrary
+{
+public:
+    static dynLibrary *open(const char *p_libName);
+    ~dynLibrary();
+
+    dynFuncPtr findSymbol(const char *p_symName);
+
+private:
+    dynLibrary();
+
+private:
+#ifdef _WIN32
+    HMODULE m_lib;
+#else
+    void *m_lib;
+#endif
+};
+
+} // of namespace osUtils
+
+
+
+// Macro to compose emugl shared library name under various OS and bitness
+// eg.
+//     on x86_64, EMUGL_LIBNAME("foo") --> "lib64foo.so"
+
+#ifdef _WIN32
+#  define DLL_EXTENSION  "" // _WIN32 LoadLibrary only accept name w/o .dll extension
+#elif defined(__APPLE__)
+#  define DLL_EXTENSION  ".dylib"
+#else
+#  define DLL_EXTENSION  ".so"
+#endif
+
+#if defined(__x86_64__)
+#  define EMUGL_LIBNAME(name) "lib64" name DLL_EXTENSION
+#elif defined(__i386__)
+#  define EMUGL_LIBNAME(name) "lib" name DLL_EXTENSION
+#else
+/* This header is included by target w/o using EMUGL_LIBNAME().  Don't #error, leave it undefined */
+#endif
+
+
+#endif
diff --git a/opengl/shared/OpenglOsUtils/osProcess.h b/opengl/shared/OpenglOsUtils/osProcess.h
new file mode 100644
index 0000000..82b31b3
--- /dev/null
+++ b/opengl/shared/OpenglOsUtils/osProcess.h
@@ -0,0 +1,62 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#ifndef _OSUTILS_PROCESS_H
+#define _OSUTILS_PROCESS_H
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+namespace osUtils {
+
+class childProcess
+{
+public:
+    static childProcess *create(const char *p_cmdLine, const char *p_startdir);
+    ~childProcess();
+
+    int getPID()
+    {
+#ifdef _WIN32
+        return m_proc.dwProcessId;
+#else
+        return(m_pid);
+#endif
+    }
+
+    int tryWait(bool& isAlive);
+    bool wait(int *exitStatus);
+
+private:
+    childProcess() {};
+
+private:
+#ifdef _WIN32
+    PROCESS_INFORMATION m_proc;
+#else
+    int m_pid;
+#endif
+};
+
+int ProcessGetPID();
+int ProcessGetTID();
+bool ProcessGetName(char *p_outName, int p_outNameLen);
+int KillProcess(int pid, bool wait);
+bool isProcessRunning(int pid);
+
+} // of namespace osUtils
+
+#endif
diff --git a/opengl/shared/OpenglOsUtils/osProcessUnix.cpp b/opengl/shared/OpenglOsUtils/osProcessUnix.cpp
new file mode 100644
index 0000000..c97ff58
--- /dev/null
+++ b/opengl/shared/OpenglOsUtils/osProcessUnix.cpp
@@ -0,0 +1,210 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#include "osProcess.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/wait.h>
+#include <sys/types.h>
+#include <poll.h>
+#include <pthread.h>
+#include <string.h>
+#include <pwd.h>
+#include <paths.h>
+#include <errno.h>
+#include <signal.h>
+#include <unistd.h>
+#include <assert.h>
+
+namespace osUtils {
+
+//
+// buildArgList converts a command line into null terminated argument list.
+// to be used with execv or execvp.
+// each argument is seperated by space or tab, to specify multiple words
+// at the same argument place it inside single-quoted or double-quoted string.
+//
+static char **buildArgList(const char *command)
+{
+    char **argv = NULL;
+    int argvSize = 0;
+    int nArgs = 0;
+    char *tmpcmd = strdup(command);
+    char *t = tmpcmd;
+    char *strStart = NULL;
+    int i = 0;
+
+    #define ADD_ARG \
+        { \
+            nArgs++; \
+            if (!argv) { \
+                argvSize = 12; \
+                argv = (char **)malloc(argvSize * sizeof(char *)); \
+            } \
+            else if (nArgs > argvSize) { \
+                argvSize += 12; \
+                argv = (char **)realloc(argv, argvSize * sizeof(char *)); \
+            } \
+            argv[nArgs-1] = t; \
+            t = NULL; \
+        }
+
+    while( tmpcmd[i] != '\0' ) {
+        if (!strStart) {
+            if (tmpcmd[i] == '"' || tmpcmd[i] == '\'') {
+                strStart = &tmpcmd[i];
+            }
+            else if (tmpcmd[i] == ' ' || tmpcmd[i] == '\t') {
+                tmpcmd[i] = '\0';
+                if (t) ADD_ARG;
+            }
+            else if (!t) {
+                t = &tmpcmd[i];
+            }
+        }
+        else if (tmpcmd[i] == *strStart) {
+            t = strStart;
+            strStart = NULL;
+        }
+
+        i++;
+    }
+    if (t) {
+        ADD_ARG;
+    }
+    if (nArgs > 0) {
+        ADD_ARG; // for NULL terminating list
+    }
+
+    return argv;
+}
+
+static pid_t start_process(const char *command,const char *startDir)
+{
+    pid_t pid;
+
+    pid = fork();
+
+    if (pid < 0) {
+        return pid;
+    }
+    else if (pid == 0) {
+        //
+        // Close all opened file descriptors
+        //
+        for (int i=3; i<256; i++) {
+            close(i);
+        }
+
+        if (startDir) {
+            chdir(startDir);
+        }
+
+        char **argv = buildArgList(command);
+        if (!argv) {
+            return -1;
+        }
+        execvp(argv[0], argv);
+
+        perror("execl");
+        exit(-101);
+    }
+
+    return pid;
+}
+
+childProcess *
+childProcess::create(const char *p_cmdLine, const char *p_startdir)
+{
+    childProcess *child = new childProcess();
+    if (!child) {
+        return NULL;
+    }
+
+    child->m_pid = start_process(p_cmdLine, p_startdir);
+    if (child->m_pid < 0) {
+        delete child;
+        return NULL;
+    }
+
+    return child;
+}
+
+childProcess::~childProcess()
+{
+}
+
+bool
+childProcess::wait(int *exitStatus)
+{
+    int ret=0;
+    if (m_pid>0) {
+        pid_t pid = waitpid(m_pid,&ret,0);
+        if (pid != -1) {
+            m_pid=-1;
+            if (exitStatus) {
+                *exitStatus = ret;
+            }
+            return true;
+        }
+    }
+    return false;
+}
+
+int
+childProcess::tryWait(bool &isAlive)
+{
+    int ret=0;
+    isAlive = false;
+    if (m_pid>0) {
+        pid_t pid = waitpid(m_pid,&ret,WNOHANG);
+        if (pid == 0) {
+            isAlive = true;
+        }
+    }
+
+    return ((char)WEXITSTATUS(ret));
+}
+
+int ProcessGetPID()
+{
+    return getpid();
+}
+
+int KillProcess(int pid, bool wait)
+{
+    if (pid<1) {
+        return false;
+    }
+
+    if (0!=kill(pid,SIGTERM)) {
+        return false;
+    }
+
+    if (wait) {
+        if (waitpid(pid,NULL,0)<0) {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+bool isProcessRunning(int pid)
+{
+    return (kill(pid,0) == 0);
+}
+
+} // of namespace osUtils
diff --git a/opengl/shared/OpenglOsUtils/osProcessWin.cpp b/opengl/shared/OpenglOsUtils/osProcessWin.cpp
new file mode 100644
index 0000000..6ff0fdf
--- /dev/null
+++ b/opengl/shared/OpenglOsUtils/osProcessWin.cpp
@@ -0,0 +1,171 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#include "osProcess.h"
+#include <windows.h>
+#include <string>
+#include <stdlib.h>
+#include <psapi.h>
+
+namespace osUtils {
+
+childProcess *
+childProcess::create(const char *p_cmdLine, const char *p_startdir)
+{
+    childProcess *child = new childProcess();
+    if (!child) {
+        return NULL;
+    }
+
+    STARTUPINFOA        si;
+    ZeroMemory(&si, sizeof(si));
+
+    ZeroMemory(&child->m_proc, sizeof(child->m_proc));
+    BOOL ret = CreateProcessA(
+                    NULL ,
+                    (LPSTR)p_cmdLine,
+                    NULL,
+                    NULL,
+                    FALSE,
+                    CREATE_DEFAULT_ERROR_MODE,
+                    NULL,
+                    (p_startdir != NULL ? p_startdir : ".\\"),
+                    &si,
+                    &child->m_proc);
+    if (ret == 0) {
+        delete child;
+        return NULL;
+    }
+
+    // close the thread handle we do not need it,
+    // keep the process handle for wait/trywait operations, will
+    // be closed on destruction
+    CloseHandle(child->m_proc.hThread);
+
+    return child;
+}
+
+childProcess::~childProcess()
+{
+    if (m_proc.hProcess) {
+        CloseHandle(m_proc.hProcess);
+    }
+}
+
+bool
+childProcess::wait(int *exitStatus)
+{
+DWORD _exitStatus;
+
+    if (WaitForSingleObject(m_proc.hProcess, INFINITE) == WAIT_FAILED) {
+        return false;
+    }
+
+    if (!GetExitCodeProcess(m_proc.hProcess, &_exitStatus))
+    {
+        return false;
+    }
+
+    if (exitStatus) {
+        *exitStatus = _exitStatus;
+    }
+
+    return true;
+}
+
+int
+childProcess::tryWait(bool& isAlive)
+{
+    DWORD status = WaitForSingleObject(m_proc.hProcess, 0);
+
+    if(status == WAIT_OBJECT_0)
+    {
+        // process has exited
+        isAlive = false;
+        GetExitCodeProcess(m_proc.hProcess, &status);
+    }
+    else if (status == WAIT_TIMEOUT)
+    {
+        isAlive = true;
+        status = 0;
+    }
+
+    return status;
+
+}
+
+int ProcessGetPID()
+{
+    return GetCurrentProcessId();
+}
+
+int ProcessGetTID()
+{
+    return GetCurrentThreadId();
+}
+
+bool ProcessGetName(char *p_outName, int p_outNameLen)
+{
+    return 0 != GetModuleFileNameEx( GetCurrentProcess(), NULL, p_outName, p_outNameLen);
+}
+
+int KillProcess(int pid, bool wait)
+{
+    DWORD exitStatus = 1;
+    HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
+
+    if (NULL == hProc) {
+        return 0;
+    }
+
+    //
+    // Terminate the process
+    //
+    TerminateProcess(hProc, 0x55);
+
+    if (wait) {
+        //
+        // Wait for it to be terminated
+        //
+        if(WaitForSingleObject(hProc, INFINITE) == WAIT_FAILED) {
+            CloseHandle(hProc);
+            return 0;
+        }
+
+        if (!GetExitCodeProcess(hProc, &exitStatus)) {
+            CloseHandle(hProc);
+            return 0;
+        }
+    }
+
+    CloseHandle(hProc);
+
+    return exitStatus;
+}
+
+bool isProcessRunning(int pid)
+{
+    bool isRunning = false;
+
+    HANDLE process = OpenProcess(SYNCHRONIZE, FALSE, pid);
+    if (NULL != process) {
+        DWORD ret = WaitForSingleObject(process, 0);
+        CloseHandle(process);
+        isRunning = (ret == WAIT_TIMEOUT);
+    }
+    return isRunning;
+}
+
+} // of namespace osUtils
diff --git a/opengl/shared/OpenglOsUtils/osThread.h b/opengl/shared/OpenglOsUtils/osThread.h
new file mode 100644
index 0000000..970396d
--- /dev/null
+++ b/opengl/shared/OpenglOsUtils/osThread.h
@@ -0,0 +1,60 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#ifndef _OSUTILS_THREAD_H
+#define _OSUTILS_THREAD_H
+
+#ifdef _WIN32
+#include <windows.h>
+#else // !WIN32
+#include <pthread.h>
+#endif
+
+namespace osUtils {
+
+class Thread
+{
+public:
+    Thread();
+    virtual ~Thread();
+
+    virtual int Main() = 0;
+
+    bool start();
+    bool  wait(int *exitStatus);
+    bool trywait(int *exitStatus);
+
+private:
+#ifdef _WIN32
+    static DWORD WINAPI thread_main(void *p_arg);
+#else // !WIN32
+    static void* thread_main(void *p_arg);
+#endif
+
+private:
+#ifdef _WIN32
+    HANDLE m_thread;
+    DWORD m_threadId;
+#else // !WIN32
+    pthread_t m_thread;
+    int       m_exitStatus;
+    pthread_mutex_t m_lock;
+#endif
+    bool m_isRunning;
+};
+
+} // of namespace osUtils
+
+#endif
diff --git a/opengl/shared/OpenglOsUtils/osThreadUnix.cpp b/opengl/shared/OpenglOsUtils/osThreadUnix.cpp
new file mode 100644
index 0000000..d8879eb
--- /dev/null
+++ b/opengl/shared/OpenglOsUtils/osThreadUnix.cpp
@@ -0,0 +1,94 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#include "osThread.h"
+
+namespace osUtils {
+
+Thread::Thread() :
+    m_thread((pthread_t)NULL),
+    m_exitStatus(0),
+    m_isRunning(false)
+{
+    pthread_mutex_init(&m_lock, NULL);
+}
+
+Thread::~Thread()
+{
+    pthread_mutex_destroy(&m_lock);
+}
+
+bool
+Thread::start()
+{
+    pthread_mutex_lock(&m_lock);
+    m_isRunning = true;
+    int ret = pthread_create(&m_thread, NULL, Thread::thread_main, this);
+    if(ret) {
+        m_isRunning = false;
+    }
+    pthread_mutex_unlock(&m_lock);
+    return m_isRunning;
+}
+
+bool
+Thread::wait(int *exitStatus)
+{
+    if (!m_isRunning) {
+        return false;
+    }
+
+    void *retval;
+    if (pthread_join(m_thread,&retval)) {
+        return false;
+    }
+
+    long long int ret=(long long int)retval;
+    if (exitStatus) {
+        *exitStatus = (int)ret;
+    }
+    return true;
+}
+
+bool
+Thread::trywait(int *exitStatus)
+{
+    bool ret = false;
+
+    pthread_mutex_lock(&m_lock);
+    if (!m_isRunning) {
+        *exitStatus = m_exitStatus;
+        ret = true;
+    }
+    pthread_mutex_unlock(&m_lock);
+    return ret;
+}
+
+void *
+Thread::thread_main(void *p_arg)
+{
+    Thread *self = (Thread *)p_arg;
+    int ret = self->Main();
+
+    pthread_mutex_lock(&self->m_lock);
+    self->m_isRunning = false;
+    self->m_exitStatus = ret;
+    pthread_mutex_unlock(&self->m_lock);
+
+    return (void*)ret;
+}
+
+} // of namespace osUtils
+
diff --git a/opengl/shared/OpenglOsUtils/osThreadWin.cpp b/opengl/shared/OpenglOsUtils/osThreadWin.cpp
new file mode 100644
index 0000000..2d563f8
--- /dev/null
+++ b/opengl/shared/OpenglOsUtils/osThreadWin.cpp
@@ -0,0 +1,101 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#include "osThread.h"
+
+namespace osUtils {
+
+Thread::Thread() :
+    m_thread(NULL),
+    m_threadId(0),
+    m_isRunning(false)
+{
+}
+
+Thread::~Thread()
+{
+    if(m_thread) {
+        CloseHandle(m_thread);
+    }
+}
+
+bool
+Thread::start()
+{
+    m_isRunning = true;
+    m_thread = CreateThread(NULL, 0, &Thread::thread_main, this, 0, &m_threadId);
+    if(!m_thread) {
+        m_isRunning = false;
+    }
+    return m_isRunning;
+}
+
+bool
+Thread::wait(int *exitStatus)
+{
+    if (!m_isRunning) {
+        return false;
+    }
+
+    if(WaitForSingleObject(m_thread, INFINITE) == WAIT_FAILED) {
+        return false;
+    }
+
+    DWORD retval;
+    if (!GetExitCodeThread(m_thread,&retval)) {
+        return false;
+    }
+
+    m_isRunning = 0;
+
+    if (exitStatus) {
+        *exitStatus = retval;
+    }
+    return true;
+}
+
+bool
+Thread::trywait(int *exitStatus)
+{
+    if (!m_isRunning) {
+        return false;
+    }
+
+    if(WaitForSingleObject(m_thread, 0) == WAIT_OBJECT_0) {
+
+        DWORD retval;
+        if (!GetExitCodeThread(m_thread,&retval)) {
+            return true;
+        }
+
+        if (exitStatus) {
+            *exitStatus = retval;
+        }
+        return true;
+    }
+
+    return false;
+}
+
+DWORD WINAPI
+Thread::thread_main(void *p_arg)
+{
+    Thread *self = (Thread *)p_arg;
+    int ret = self->Main();
+    self->m_isRunning = false;
+    return ret;
+}
+
+} // of namespace osUtils
diff --git a/opengl/system/GLESv1/Android.mk b/opengl/system/GLESv1/Android.mk
new file mode 100644
index 0000000..97356b7
--- /dev/null
+++ b/opengl/system/GLESv1/Android.mk
@@ -0,0 +1,12 @@
+LOCAL_PATH := $(call my-dir)
+
+### GLESv1 implementation ###########################################
+$(call emugl-begin-shared-library,libGLESv1_CM_emulation)
+$(call emugl-import,libOpenglSystemCommon libGLESv1_enc lib_renderControl_enc)
+
+LOCAL_CFLAGS += -DLOG_TAG=\"GLES_emulation\" -DGL_GLEXT_PROTOTYPES
+
+LOCAL_SRC_FILES := gl.cpp
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/egl
+
+$(call emugl-end-module)
diff --git a/opengl/system/GLESv1/gl.cpp b/opengl/system/GLESv1/gl.cpp
new file mode 100644
index 0000000..8ecb504
--- /dev/null
+++ b/opengl/system/GLESv1/gl.cpp
@@ -0,0 +1,146 @@
+/*
+* Copyright 2011 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.
+*/
+
+#include "EGLClientIface.h"
+#include "HostConnection.h"
+#include "GLEncoder.h"
+#include "GLES/gl.h"
+#include "GLES/glext.h"
+#include "ErrorLog.h"
+#include "gralloc_cb.h"
+#include "ThreadInfo.h"
+
+
+//XXX: fix this macro to get the context from fast tls path
+#define GET_CONTEXT GLEncoder * ctx = getEGLThreadInfo()->hostConn->glEncoder();
+
+#include "gl_entry.cpp"
+
+//The functions table
+#include "gl_ftable.h"
+
+static EGLClient_eglInterface * s_egl = NULL;
+static EGLClient_glesInterface * s_gl = NULL;
+
+#define DEFINE_AND_VALIDATE_HOST_CONNECTION(ret) \
+    HostConnection *hostCon = HostConnection::get(); \
+    if (!hostCon) { \
+        ALOGE("egl: Failed to get host connection\n"); \
+        return ret; \
+    } \
+    renderControl_encoder_context_t *rcEnc = hostCon->rcEncoder(); \
+    if (!rcEnc) { \
+        ALOGE("egl: Failed to get renderControl encoder context\n"); \
+        return ret; \
+    }
+
+//GL extensions
+void glEGLImageTargetTexture2DOES(void * self, GLenum target, GLeglImageOES image)
+{
+    DBG("glEGLImageTargetTexture2DOES v1 target=%#x image=%p", target, image);
+    //TODO: check error - we don't have a way to set gl error
+    android_native_buffer_t* native_buffer = (android_native_buffer_t*)image;
+
+    if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) {
+        return;
+    }
+
+    if (native_buffer->common.version != sizeof(android_native_buffer_t)) {
+        return;
+    }
+
+    GET_CONTEXT;
+    DEFINE_AND_VALIDATE_HOST_CONNECTION();
+
+    ctx->override2DTextureTarget(target);
+    rcEnc->rcBindTexture(rcEnc,
+            ((cb_handle_t *)(native_buffer->handle))->hostHandle);
+    ctx->restore2DTextureTarget();
+
+    return;
+}
+
+void glEGLImageTargetRenderbufferStorageOES(void *self, GLenum target, GLeglImageOES image)
+{
+    DBG("glEGLImageTargetRenderbufferStorageOES v1 target=%#x image=%p",
+            target, image);
+    //TODO: check error - we don't have a way to set gl error
+    android_native_buffer_t* native_buffer = (android_native_buffer_t*)image;
+
+    if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) {
+        return;
+    }
+
+    if (native_buffer->common.version != sizeof(android_native_buffer_t)) {
+        return;
+    }
+
+    DEFINE_AND_VALIDATE_HOST_CONNECTION();
+    rcEnc->rcBindRenderbuffer(rcEnc,
+            ((cb_handle_t *)(native_buffer->handle))->hostHandle);
+
+    return;
+}
+
+void * getProcAddress(const char * procname)
+{
+    // search in GL function table
+    for (int i=0; i<gl_num_funcs; i++) {
+        if (!strcmp(gl_funcs_by_name[i].name, procname)) {
+            return gl_funcs_by_name[i].proc;
+        }
+    }
+    return NULL;
+}
+
+void finish()
+{
+    glFinish();
+}
+
+const GLubyte *my_glGetString (void *self, GLenum name)
+{
+    if (s_egl) {
+        return (const GLubyte*)s_egl->getGLString(name);
+    }
+    return NULL;
+}
+
+void init()
+{
+    GET_CONTEXT;
+    ctx->set_glEGLImageTargetTexture2DOES(glEGLImageTargetTexture2DOES);
+    ctx->set_glEGLImageTargetRenderbufferStorageOES(glEGLImageTargetRenderbufferStorageOES);
+    ctx->set_glGetString(my_glGetString);
+}
+
+extern "C" {
+EGLClient_glesInterface * init_emul_gles(EGLClient_eglInterface *eglIface)
+{
+    s_egl = eglIface;
+
+    if (!s_gl) {
+        s_gl = new EGLClient_glesInterface();
+        s_gl->getProcAddress = getProcAddress;
+        s_gl->finish = finish;
+        s_gl->init = init;
+    }
+
+    return s_gl;
+}
+} //extern
+
+
diff --git a/opengl/system/GLESv1_enc/Android.mk b/opengl/system/GLESv1_enc/Android.mk
new file mode 100644
index 0000000..fd12395
--- /dev/null
+++ b/opengl/system/GLESv1_enc/Android.mk
@@ -0,0 +1,19 @@
+LOCAL_PATH := $(call my-dir)
+
+### GLESv1_enc Encoder ###########################################
+$(call emugl-begin-shared-library,libGLESv1_enc)
+
+LOCAL_CFLAGS += -DLOG_TAG=\"emuglGLESv1_enc\"
+
+LOCAL_SRC_FILES := \
+        GLEncoder.cpp \
+        GLEncoderUtils.cpp \
+        gl_client_context.cpp \
+        gl_enc.cpp \
+        gl_entry.cpp
+
+$(call emugl-import,libOpenglCodecCommon)
+$(call emugl-export,C_INCLUDES,$(LOCAL_PATH))
+$(call emugl-export,C_INCLUDES,$(intermediates))
+
+$(call emugl-end-module)
diff --git a/opengl/system/GLESv1_enc/GLEncoder.cpp b/opengl/system/GLESv1_enc/GLEncoder.cpp
new file mode 100644
index 0000000..4414f24
--- /dev/null
+++ b/opengl/system/GLESv1_enc/GLEncoder.cpp
@@ -0,0 +1,989 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#include "GLEncoder.h"
+#include "glUtils.h"
+#include "FixedBuffer.h"
+#include <cutils/log.h>
+#include <assert.h>
+
+#ifndef MIN
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#endif
+
+static GLubyte *gVendorString= (GLubyte *) "Android";
+static GLubyte *gRendererString= (GLubyte *) "Android HW-GLES 1.0";
+static GLubyte *gVersionString= (GLubyte *) "OpenGL ES-CM 1.0";
+static GLubyte *gExtensionsString= (GLubyte *) ""; // no extensions at this point;
+
+#define SET_ERROR_IF(condition,err) if((condition)) {                            \
+        ALOGE("%s:%s:%d GL error 0x%x\n", __FILE__, __FUNCTION__, __LINE__, err); \
+        ctx->setError(err);                                    \
+        return;                                                  \
+    }
+
+
+#define RET_AND_SET_ERROR_IF(condition,err,ret) if((condition)) {                \
+        ALOGE("%s:%s:%d GL error 0x%x\n", __FILE__, __FUNCTION__, __LINE__, err); \
+        ctx->setError(err);                                    \
+        return ret;                                              \
+    }
+
+GLenum GLEncoder::s_glGetError(void * self)
+{
+    GLEncoder *ctx = (GLEncoder *)self;
+    GLenum err = ctx->getError();
+    if(err != GL_NO_ERROR) {
+        ctx->setError(GL_NO_ERROR);
+        return err;
+    }
+
+    return ctx->m_glGetError_enc(self);
+
+}
+
+GLint * GLEncoder::getCompressedTextureFormats()
+{
+    if (m_compressedTextureFormats == NULL) {
+        this->glGetIntegerv(this, GL_NUM_COMPRESSED_TEXTURE_FORMATS,
+                            &m_num_compressedTextureFormats);
+        if (m_num_compressedTextureFormats > 0) {
+            // get number of texture formats;
+            m_compressedTextureFormats = new GLint[m_num_compressedTextureFormats];
+            this->glGetCompressedTextureFormats(this, m_num_compressedTextureFormats, m_compressedTextureFormats);
+        }
+    }
+    return m_compressedTextureFormats;
+}
+
+void GLEncoder::s_glGetIntegerv(void *self, GLenum param, GLint *ptr)
+{
+    GLEncoder *ctx = (GLEncoder *)self;
+    assert(ctx->m_state != NULL);
+    GLClientState* state = ctx->m_state;
+
+    switch (param) {
+    case GL_COMPRESSED_TEXTURE_FORMATS: {
+        GLint * compressedTextureFormats = ctx->getCompressedTextureFormats();
+        if (ctx->m_num_compressedTextureFormats > 0 &&
+                compressedTextureFormats != NULL) {
+            memcpy(ptr, compressedTextureFormats,
+                   ctx->m_num_compressedTextureFormats * sizeof(GLint));
+        }
+        break;
+    }
+
+    case GL_MAX_TEXTURE_UNITS:
+        ctx->m_glGetIntegerv_enc(self, param, ptr);
+        *ptr = MIN(*ptr, GLClientState::MAX_TEXTURE_UNITS);
+        break;
+
+    case GL_TEXTURE_BINDING_2D:
+        *ptr = state->getBoundTexture(GL_TEXTURE_2D);
+        break;
+
+    case GL_TEXTURE_BINDING_EXTERNAL_OES:
+        *ptr = state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES);
+        break;
+
+    default:
+        if (!state->getClientStateParameter<GLint>(param,ptr)) {
+            ctx->m_glGetIntegerv_enc(self, param, ptr);
+        }
+        break;
+    }
+}
+
+void GLEncoder::s_glGetFloatv(void *self, GLenum param, GLfloat *ptr)
+{
+    GLEncoder *ctx = (GLEncoder *)self;
+    assert(ctx->m_state != NULL);
+    GLClientState* state = ctx->m_state;
+
+    switch (param) {
+    case GL_COMPRESSED_TEXTURE_FORMATS: {
+        GLint * compressedTextureFormats = ctx->getCompressedTextureFormats();
+        if (ctx->m_num_compressedTextureFormats > 0 &&
+                compressedTextureFormats != NULL) {
+            for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) {
+                ptr[i] = (GLfloat) compressedTextureFormats[i];
+            }
+        }
+        break;
+    }
+
+    case GL_MAX_TEXTURE_UNITS:
+        ctx->m_glGetFloatv_enc(self, param, ptr);
+        *ptr = MIN(*ptr, (GLfloat)GLClientState::MAX_TEXTURE_UNITS);
+        break;
+
+    case GL_TEXTURE_BINDING_2D:
+        *ptr = (GLfloat)state->getBoundTexture(GL_TEXTURE_2D);
+        break;
+
+    case GL_TEXTURE_BINDING_EXTERNAL_OES:
+        *ptr = (GLfloat)state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES);
+        break;
+
+    default:
+        if (!state->getClientStateParameter<GLfloat>(param,ptr)) {
+            ctx->m_glGetFloatv_enc(self, param, ptr);
+        }
+        break;
+    }
+}
+
+void GLEncoder::s_glGetFixedv(void *self, GLenum param, GLfixed *ptr)
+{
+    GLEncoder *ctx = (GLEncoder *)self;
+    assert(ctx->m_state != NULL);
+    GLClientState* state = ctx->m_state;
+
+    switch (param) {
+    case GL_COMPRESSED_TEXTURE_FORMATS: {
+        GLint * compressedTextureFormats = ctx->getCompressedTextureFormats();
+        if (ctx->m_num_compressedTextureFormats > 0 &&
+                compressedTextureFormats != NULL) {
+            for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) {
+                ptr[i] =  compressedTextureFormats[i] << 16;
+            }
+        }
+        break;
+    }
+
+    case GL_MAX_TEXTURE_UNITS:
+        ctx->m_glGetFixedv_enc(self, param, ptr);
+        *ptr = MIN(*ptr, GLClientState::MAX_TEXTURE_UNITS << 16);
+        break;
+
+    case GL_TEXTURE_BINDING_2D:
+        *ptr = state->getBoundTexture(GL_TEXTURE_2D) << 16;
+        break;
+
+    case GL_TEXTURE_BINDING_EXTERNAL_OES:
+        *ptr = state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES) << 16;
+        break;
+
+    default:
+        if (!state->getClientStateParameter<GLfixed>(param,ptr)) {
+            ctx->m_glGetFixedv_enc(self, param, ptr);
+        }
+        break;
+    }
+}
+
+void GLEncoder::s_glGetBooleanv(void *self, GLenum param, GLboolean *ptr)
+{
+    GLEncoder *ctx = (GLEncoder *)self;
+    assert(ctx->m_state != NULL);
+    GLClientState* state = ctx->m_state;
+
+    switch (param) {
+    case GL_COMPRESSED_TEXTURE_FORMATS: {
+        GLint* compressedTextureFormats = ctx->getCompressedTextureFormats();
+        if (ctx->m_num_compressedTextureFormats > 0 &&
+                compressedTextureFormats != NULL) {
+            for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) {
+                ptr[i] = compressedTextureFormats[i] != 0 ? GL_TRUE : GL_FALSE;
+            }
+        }
+        break;
+    }
+
+    case GL_TEXTURE_BINDING_2D:
+        *ptr = state->getBoundTexture(GL_TEXTURE_2D) != 0 ? GL_TRUE : GL_FALSE;
+        break;
+
+    case GL_TEXTURE_BINDING_EXTERNAL_OES:
+        *ptr = state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES) != 0
+                ? GL_TRUE : GL_FALSE;
+        break;
+
+    default:
+        if (!state->getClientStateParameter<GLboolean>(param,ptr)) {
+            ctx->m_glGetBooleanv_enc(self, param, ptr);
+        }
+        break;
+    }
+}
+
+void GLEncoder::s_glGetPointerv(void * self, GLenum param, GLvoid **params)
+{
+    GLEncoder * ctx = (GLEncoder *) self;
+    assert(ctx->m_state != NULL);
+    ctx->m_state->getClientStatePointer(param,params);
+}
+
+void GLEncoder::s_glFlush(void *self)
+{
+    GLEncoder *ctx = (GLEncoder *)self;
+    ctx->m_glFlush_enc(self);
+    ctx->m_stream->flush();
+}
+
+const GLubyte *GLEncoder::s_glGetString(void *self, GLenum name)
+{
+    GLubyte *retval =  (GLubyte *) "";
+    switch(name) {
+    case GL_VENDOR:
+        retval = gVendorString;
+        break;
+    case GL_RENDERER:
+        retval = gRendererString;
+        break;
+    case GL_VERSION:
+        retval = gVersionString;
+        break;
+    case GL_EXTENSIONS:
+        retval = gExtensionsString;
+        break;
+    }
+    return retval;
+}
+
+void GLEncoder::s_glPixelStorei(void *self, GLenum param, GLint value)
+{
+    GLEncoder *ctx = (GLEncoder *)self;
+    ctx->m_glPixelStorei_enc(ctx, param, value);
+    ALOG_ASSERT(ctx->m_state, "GLEncoder::s_glPixelStorei");
+    ctx->m_state->setPixelStore(param, value);
+}
+
+void GLEncoder::s_glVertexPointer(void *self, int size, GLenum type, GLsizei stride, const void *data)
+{
+    GLEncoder *ctx = (GLEncoder *)self;
+    assert(ctx->m_state != NULL);
+    ctx->m_state->setState(GLClientState::VERTEX_LOCATION, size, type, false, stride, data);
+}
+
+void GLEncoder::s_glNormalPointer(void *self, GLenum type, GLsizei stride, const void *data)
+{
+    GLEncoder *ctx = (GLEncoder *)self;
+    assert(ctx->m_state != NULL);
+    ctx->m_state->setState(GLClientState::NORMAL_LOCATION, 3, type, false, stride, data);
+}
+
+void GLEncoder::s_glColorPointer(void *self, int size, GLenum type, GLsizei stride, const void *data)
+{
+    GLEncoder *ctx = (GLEncoder *)self;
+    assert(ctx->m_state != NULL);
+    ctx->m_state->setState(GLClientState::COLOR_LOCATION, size, type, false, stride, data);
+}
+
+void GLEncoder::s_glPointsizePointer(void *self, GLenum type, GLsizei stride, const void *data)
+{
+    GLEncoder *ctx = (GLEncoder *)self;
+    assert(ctx->m_state != NULL);
+    ctx->m_state->setState(GLClientState::POINTSIZE_LOCATION, 1, type, false, stride, data);
+}
+
+void GLEncoder::s_glClientActiveTexture(void *self, GLenum texture)
+{
+    GLEncoder *ctx = (GLEncoder *)self;
+    assert(ctx->m_state != NULL);
+    ctx->m_state->setActiveTexture(texture - GL_TEXTURE0);
+}
+
+void GLEncoder::s_glTexcoordPointer(void *self, int size, GLenum type, GLsizei stride, const void *data)
+{
+    GLEncoder *ctx = (GLEncoder *)self;
+    assert(ctx->m_state != NULL);
+    int loc = ctx->m_state->getLocation(GL_TEXTURE_COORD_ARRAY);
+    ctx->m_state->setState(loc, size, type, false, stride, data);
+}
+
+void GLEncoder::s_glMatrixIndexPointerOES(void *self, int size, GLenum type, GLsizei stride, const void * data)
+{
+    GLEncoder *ctx = (GLEncoder *)self;
+    assert(ctx->m_state != NULL);
+    int loc = ctx->m_state->getLocation(GL_MATRIX_INDEX_ARRAY_OES);
+    ctx->m_state->setState(loc, size, type, false, stride, data);
+}
+
+void GLEncoder::s_glWeightPointerOES(void * self, int size, GLenum type, GLsizei stride, const void * data)
+{
+    GLEncoder *ctx = (GLEncoder *)self;
+    assert(ctx->m_state != NULL);
+    int loc = ctx->m_state->getLocation(GL_WEIGHT_ARRAY_OES);
+    ctx->m_state->setState(loc, size, type, false, stride, data);
+}
+
+void GLEncoder::s_glEnableClientState(void *self, GLenum state)
+{
+    GLEncoder *ctx = (GLEncoder *) self;
+    assert(ctx->m_state != NULL);
+    int loc = ctx->m_state->getLocation(state);
+    ctx->m_state->enable(loc, 1);
+}
+
+void GLEncoder::s_glDisableClientState(void *self, GLenum state)
+{
+    GLEncoder *ctx = (GLEncoder *) self;
+    assert(ctx->m_state != NULL);
+    int loc = ctx->m_state->getLocation(state);
+    ctx->m_state->enable(loc, 0);
+}
+
+GLboolean GLEncoder::s_glIsEnabled(void *self, GLenum cap)
+{
+    GLEncoder *ctx = (GLEncoder *) self;
+    assert(ctx->m_state != NULL);
+    int loc = ctx->m_state->getLocation(cap);
+    const GLClientState::VertexAttribState *state = ctx->m_state->getState(loc);
+
+    if (state!=NULL)
+      return state->enabled;
+
+    return ctx->m_glIsEnabled_enc(self,cap);
+}
+
+void GLEncoder::s_glBindBuffer(void *self, GLenum target, GLuint id)
+{
+    GLEncoder *ctx = (GLEncoder *) self;
+    assert(ctx->m_state != NULL);
+    ctx->m_state->bindBuffer(target, id);
+    // TODO set error state if needed;
+    ctx->m_glBindBuffer_enc(self, target, id);
+}
+
+void GLEncoder::s_glBufferData(void * self, GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage)
+{
+    GLEncoder *ctx = (GLEncoder *) self;
+    GLuint bufferId = ctx->m_state->getBuffer(target);
+    SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION);
+    SET_ERROR_IF(size<0, GL_INVALID_VALUE);
+
+    ctx->m_shared->updateBufferData(bufferId, size, (void*)data);
+    ctx->m_glBufferData_enc(self, target, size, data, usage);
+}
+
+void GLEncoder::s_glBufferSubData(void * self, GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data)
+{
+    GLEncoder *ctx = (GLEncoder *) self;
+    GLuint bufferId = ctx->m_state->getBuffer(target);
+    SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION);
+
+    GLenum res = ctx->m_shared->subUpdateBufferData(bufferId, offset, size, (void*)data);
+    SET_ERROR_IF(res, res);
+
+    ctx->m_glBufferSubData_enc(self, target, offset, size, data);
+}
+
+void GLEncoder::s_glDeleteBuffers(void * self, GLsizei n, const GLuint * buffers)
+{
+    GLEncoder *ctx = (GLEncoder *) self;
+    SET_ERROR_IF(n<0, GL_INVALID_VALUE);
+    for (int i=0; i<n; i++) {
+        ctx->m_shared->deleteBufferData(buffers[i]);
+        ctx->m_glDeleteBuffers_enc(self,1,&buffers[i]);
+    }
+}
+
+void GLEncoder::sendVertexData(unsigned int first, unsigned int count)
+{
+    assert(m_state != NULL);
+    for (int i = 0; i < GLClientState::LAST_LOCATION; i++) {
+        bool enableDirty;
+        const GLClientState::VertexAttribState *state = m_state->getStateAndEnableDirty(i, &enableDirty);
+
+        // do not process if state not valid
+        if (!state) continue;
+
+        // do not send disable state if state was already disabled
+        if (!enableDirty && !state->enabled) continue;
+
+        if ( i >= GLClientState::TEXCOORD0_LOCATION &&
+            i <= GLClientState::TEXCOORD7_LOCATION ) {
+            m_glClientActiveTexture_enc(this, GL_TEXTURE0 + i - GLClientState::TEXCOORD0_LOCATION);
+        }
+
+        if (state->enabled) {
+
+            if (enableDirty)
+                m_glEnableClientState_enc(this, state->glConst);
+
+            unsigned int datalen = state->elementSize * count;
+            int stride = state->stride;
+            if (stride == 0) stride = state->elementSize;
+            int firstIndex = stride * first;
+
+            if (state->bufferObject == 0) {
+
+                switch(i) {
+                case GLClientState::VERTEX_LOCATION:
+                    this->glVertexPointerData(this, state->size, state->type, state->stride,
+                                              (unsigned char *)state->data + firstIndex, datalen);
+                    break;
+                case GLClientState::NORMAL_LOCATION:
+                    this->glNormalPointerData(this, state->type, state->stride,
+                                              (unsigned char *)state->data + firstIndex, datalen);
+                    break;
+                case GLClientState::COLOR_LOCATION:
+                    this->glColorPointerData(this, state->size, state->type, state->stride,
+                                             (unsigned char *)state->data + firstIndex, datalen);
+                    break;
+                case GLClientState::TEXCOORD0_LOCATION:
+                case GLClientState::TEXCOORD1_LOCATION:
+                case GLClientState::TEXCOORD2_LOCATION:
+                case GLClientState::TEXCOORD3_LOCATION:
+                case GLClientState::TEXCOORD4_LOCATION:
+                case GLClientState::TEXCOORD5_LOCATION:
+                case GLClientState::TEXCOORD6_LOCATION:
+                case GLClientState::TEXCOORD7_LOCATION:
+                    this->glTexCoordPointerData(this, i - GLClientState::TEXCOORD0_LOCATION, state->size, state->type, state->stride,
+                                                (unsigned char *)state->data + firstIndex, datalen);
+                    break;
+                case GLClientState::POINTSIZE_LOCATION:
+                    this->glPointSizePointerData(this, state->type, state->stride,
+                                                 (unsigned char *) state->data + firstIndex, datalen);
+                    break;
+                case GLClientState::WEIGHT_LOCATION:
+                    this->glWeightPointerData(this, state->size, state->type, state->stride,
+                                              (unsigned char * ) state->data + firstIndex, datalen);
+                    break;
+                case GLClientState::MATRIXINDEX_LOCATION:
+                    this->glMatrixIndexPointerData(this, state->size, state->type, state->stride,
+                                                  (unsigned char *)state->data + firstIndex, datalen);
+                    break;
+                }
+            } else {
+                this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, state->bufferObject);
+
+                switch(i) {
+                case GLClientState::VERTEX_LOCATION:
+                    this->glVertexPointerOffset(this, state->size, state->type, state->stride,
+                                                (GLuint)state->data + firstIndex);
+                    break;
+                case GLClientState::NORMAL_LOCATION:
+                    this->glNormalPointerOffset(this, state->type, state->stride,
+                                                (GLuint) state->data + firstIndex);
+                    break;
+                case GLClientState::POINTSIZE_LOCATION:
+                    this->glPointSizePointerOffset(this, state->type, state->stride,
+                                                   (GLuint) state->data + firstIndex);
+                    break;
+                case GLClientState::COLOR_LOCATION:
+                    this->glColorPointerOffset(this, state->size, state->type, state->stride,
+                                               (GLuint) state->data + firstIndex);
+                    break;
+                case GLClientState::TEXCOORD0_LOCATION:
+                case GLClientState::TEXCOORD1_LOCATION:
+                case GLClientState::TEXCOORD2_LOCATION:
+                case GLClientState::TEXCOORD3_LOCATION:
+                case GLClientState::TEXCOORD4_LOCATION:
+                case GLClientState::TEXCOORD5_LOCATION:
+                case GLClientState::TEXCOORD6_LOCATION:
+                case GLClientState::TEXCOORD7_LOCATION:
+                    this->glTexCoordPointerOffset(this, state->size, state->type, state->stride,
+                                                  (GLuint) state->data + firstIndex);
+                    break;
+                case GLClientState::WEIGHT_LOCATION:
+                    this->glWeightPointerOffset(this,state->size,state->type,state->stride,
+                                                (GLuint)state->data+firstIndex);
+                    break;
+                case GLClientState::MATRIXINDEX_LOCATION:
+                    this->glMatrixIndexPointerOffset(this,state->size,state->type,state->stride,
+                                              (GLuint)state->data+firstIndex);
+                    break;
+                }                
+                this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, m_state->currentArrayVbo());
+            }
+        } else {
+            this->m_glDisableClientState_enc(this, state->glConst);
+        }
+    }
+}
+
+void GLEncoder::s_glDrawArrays(void *self, GLenum mode, GLint first, GLsizei count)
+{
+    GLEncoder *ctx = (GLEncoder *)self;
+
+    ctx->sendVertexData(first, count);
+    ctx->m_glDrawArrays_enc(ctx, mode, /*first*/ 0, count);
+}
+
+void GLEncoder::s_glDrawElements(void *self, GLenum mode, GLsizei count, GLenum type, const void *indices)
+{
+
+    GLEncoder *ctx = (GLEncoder *)self;
+    assert(ctx->m_state != NULL);
+    SET_ERROR_IF(count<0, GL_INVALID_VALUE);
+
+    bool has_immediate_arrays = false;
+    bool has_indirect_arrays = false;
+
+    for (int i = 0; i < GLClientState::LAST_LOCATION; i++) {
+        const GLClientState::VertexAttribState *state = ctx->m_state->getState(i);
+        if (state->enabled) {
+            if (state->bufferObject != 0) {
+                has_indirect_arrays = true;
+            } else {
+                has_immediate_arrays = true;
+            }
+        }
+    }
+
+    if (!has_immediate_arrays && !has_indirect_arrays) {
+        ALOGE("glDrawElements: no data bound to the command - ignoring\n");
+        return;
+    }
+
+    bool adjustIndices = true;
+    if (ctx->m_state->currentIndexVbo() != 0) {
+        if (!has_immediate_arrays) {
+            ctx->sendVertexData(0, count);
+            ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo());
+            ctx->glDrawElementsOffset(ctx, mode, count, type, (GLuint)indices);
+            adjustIndices = false;
+        } else {
+            BufferData * buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
+            ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, 0);
+            indices = (void*)((GLintptr)buf->m_fixedBuffer.ptr() + (GLintptr)indices);
+        }
+    } 
+    if (adjustIndices) {
+        void *adjustedIndices = (void*)indices;
+        int minIndex = 0, maxIndex = 0;
+
+        switch(type) {
+        case GL_BYTE:
+        case GL_UNSIGNED_BYTE:
+            GLUtils::minmax<unsigned char>((unsigned char *)indices, count, &minIndex, &maxIndex);
+            if (minIndex != 0) {
+                adjustedIndices =  ctx->m_fixedBuffer.alloc(glSizeof(type) * count);
+                GLUtils::shiftIndices<unsigned char>((unsigned char *)indices,
+                                                 (unsigned char *)adjustedIndices,
+                                                 count, -minIndex);
+            }
+            break;
+        case GL_SHORT:
+        case GL_UNSIGNED_SHORT:
+            GLUtils::minmax<unsigned short>((unsigned short *)indices, count, &minIndex, &maxIndex);
+            if (minIndex != 0) {
+                adjustedIndices = ctx->m_fixedBuffer.alloc(glSizeof(type) * count);
+                GLUtils::shiftIndices<unsigned short>((unsigned short *)indices,
+                                                 (unsigned short *)adjustedIndices,
+                                                 count, -minIndex);
+            }
+            break;
+        default:
+            ALOGE("unsupported index buffer type %d\n", type);
+        }
+        if (has_indirect_arrays || 1) {
+            ctx->sendVertexData(minIndex, maxIndex - minIndex + 1);
+            ctx->glDrawElementsData(ctx, mode, count, type, adjustedIndices,
+                                      count * glSizeof(type));
+            // XXX - OPTIMIZATION (see the other else branch) should be implemented
+            if(!has_indirect_arrays) {
+                //ALOGD("unoptimized drawelements !!!\n");
+            }
+        } else {
+            // we are all direct arrays and immidate mode index array -
+            // rebuild the arrays and the index array;
+            ALOGE("glDrawElements: direct index & direct buffer data - will be implemented in later versions;\n");
+        }
+    }
+}
+
+void GLEncoder::s_glActiveTexture(void* self, GLenum texture)
+{
+    GLEncoder* ctx = (GLEncoder*)self;
+    GLClientState* state = ctx->m_state;
+    GLenum err;
+
+    if ((err = state->setActiveTextureUnit(texture)) != GL_NO_ERROR) {
+        ALOGE("%s:%s:%d GL error %#x\n", __FILE__, __FUNCTION__, __LINE__, err);
+        ctx->setError(err);
+        return;
+    }
+
+    ctx->m_glActiveTexture_enc(ctx, texture);
+}
+
+void GLEncoder::s_glBindTexture(void* self, GLenum target, GLuint texture)
+{
+    GLEncoder* ctx = (GLEncoder*)self;
+    GLClientState* state = ctx->m_state;
+    GLenum err;
+
+    GLboolean firstUse;
+    if ((err = state->bindTexture(target, texture, &firstUse)) != GL_NO_ERROR) {
+        ALOGE("%s:%s:%d GL error %#x\n", __FILE__, __FUNCTION__, __LINE__, err);
+        ctx->setError(err);
+        return;
+    }
+
+    if (target != GL_TEXTURE_2D && target != GL_TEXTURE_EXTERNAL_OES) {
+        ctx->m_glBindTexture_enc(ctx, target, texture);
+        return;
+    }
+
+    GLenum priorityTarget = state->getPriorityEnabledTarget(GL_TEXTURE_2D);
+
+    if (target == GL_TEXTURE_EXTERNAL_OES && firstUse) {
+        // set TEXTURE_EXTERNAL_OES default states which differ from TEXTURE_2D
+        ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, texture);
+        ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
+                GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+        ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
+                GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+        ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
+                GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+        if (target != priorityTarget) {
+            ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D,
+                    state->getBoundTexture(GL_TEXTURE_2D));
+        }
+    }
+
+    if (target == priorityTarget) {
+        ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, texture);
+    }
+}
+
+void GLEncoder::s_glDeleteTextures(void* self, GLsizei n, const GLuint* textures)
+{
+    GLEncoder* ctx = (GLEncoder*)self;
+    GLClientState* state = ctx->m_state;
+
+    state->deleteTextures(n, textures);
+    ctx->m_glDeleteTextures_enc(ctx, n, textures);
+}
+
+void GLEncoder::s_glDisable(void* self, GLenum cap)
+{
+    GLEncoder* ctx = (GLEncoder*)self;
+    GLClientState* state = ctx->m_state;
+
+    if (cap == GL_TEXTURE_2D || cap == GL_TEXTURE_EXTERNAL_OES) {
+        GLenum prevTarget = state->getPriorityEnabledTarget(GL_INVALID_ENUM);
+        state->disableTextureTarget(cap);
+        GLenum currTarget = state->getPriorityEnabledTarget(GL_INVALID_ENUM);
+
+        if (prevTarget != currTarget) {
+            if (currTarget == GL_INVALID_ENUM) {
+                ctx->m_glDisable_enc(ctx, GL_TEXTURE_2D);
+                currTarget = GL_TEXTURE_2D;
+            }
+            // maintain the invariant that when TEXTURE_EXTERNAL_OES is
+            // disabled, the TEXTURE_2D binding is active, even if
+            // TEXTURE_2D is also disabled.
+            ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D,
+                    state->getBoundTexture(currTarget));
+        }
+
+    } else {
+        ctx->m_glDisable_enc(ctx, cap);
+    }
+}
+
+void GLEncoder::s_glEnable(void* self, GLenum cap)
+{
+    GLEncoder* ctx = (GLEncoder*)self;
+    GLClientState* state = ctx->m_state;
+
+    if (cap == GL_TEXTURE_2D || cap == GL_TEXTURE_EXTERNAL_OES) {
+        GLenum prevTarget = state->getPriorityEnabledTarget(GL_INVALID_ENUM);
+        state->enableTextureTarget(cap);
+        GLenum currTarget = state->getPriorityEnabledTarget(GL_INVALID_ENUM);
+
+        if (prevTarget != currTarget) {
+            if (prevTarget == GL_INVALID_ENUM) {
+                ctx->m_glEnable_enc(ctx, GL_TEXTURE_2D);
+            }
+            if (currTarget == GL_TEXTURE_EXTERNAL_OES) {
+                ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D,
+                        state->getBoundTexture(currTarget));
+            }
+        }
+
+    } else {
+        ctx->m_glEnable_enc(ctx, cap);
+    }
+}
+
+void GLEncoder::s_glGetTexParameterfv(void* self,
+        GLenum target, GLenum pname, GLfloat* params)
+{
+    GLEncoder* ctx = (GLEncoder*)self;
+    const GLClientState* state = ctx->m_state;
+
+    if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
+        ctx->override2DTextureTarget(target);
+        ctx->m_glGetTexParameterfv_enc(ctx, GL_TEXTURE_2D, pname, params);
+        ctx->restore2DTextureTarget();
+    } else {
+        ctx->m_glGetTexParameterfv_enc(ctx, target, pname, params);
+    }
+}
+
+void GLEncoder::s_glGetTexParameteriv(void* self,
+        GLenum target, GLenum pname, GLint* params)
+{
+    GLEncoder* ctx = (GLEncoder*)self;
+    const GLClientState* state = ctx->m_state;
+
+    switch (pname) {
+    case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
+        *params = 1;
+        break;
+
+    default:
+        if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
+            ctx->override2DTextureTarget(target);
+            ctx->m_glGetTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params);
+            ctx->restore2DTextureTarget();
+        } else {
+            ctx->m_glGetTexParameteriv_enc(ctx, target, pname, params);
+        }
+        break;
+    }
+}
+
+void GLEncoder::s_glGetTexParameterxv(void* self,
+        GLenum target, GLenum pname, GLfixed* params)
+{
+    GLEncoder* ctx = (GLEncoder*)self;
+    const GLClientState* state = ctx->m_state;
+
+    if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
+        ctx->override2DTextureTarget(target);
+        ctx->m_glGetTexParameterxv_enc(ctx, GL_TEXTURE_2D, pname, params);
+        ctx->restore2DTextureTarget();
+    } else {
+        ctx->m_glGetTexParameterxv_enc(ctx, target, pname, params);
+    }
+}
+
+static bool isValidTextureExternalParam(GLenum pname, GLenum param)
+{
+    switch (pname) {
+    case GL_TEXTURE_MIN_FILTER:
+    case GL_TEXTURE_MAG_FILTER:
+        return param == GL_NEAREST || param == GL_LINEAR;
+
+    case GL_TEXTURE_WRAP_S:
+    case GL_TEXTURE_WRAP_T:
+        return param == GL_CLAMP_TO_EDGE;
+
+    case GL_GENERATE_MIPMAP:
+        return param == GL_FALSE;
+
+    default:
+        return true;
+    }
+}
+
+void GLEncoder::s_glTexParameterf(void* self,
+        GLenum target, GLenum pname, GLfloat param)
+{
+    GLEncoder* ctx = (GLEncoder*)self;
+    const GLClientState* state = ctx->m_state;
+
+    SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
+            !isValidTextureExternalParam(pname, (GLenum)param)),
+            GL_INVALID_ENUM);
+
+    if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
+        ctx->override2DTextureTarget(target);
+        ctx->m_glTexParameterf_enc(ctx, GL_TEXTURE_2D, pname, param);
+        ctx->restore2DTextureTarget();
+    } else {
+        ctx->m_glTexParameterf_enc(ctx, target, pname, param);
+    }
+}
+
+void GLEncoder::s_glTexParameterfv(void* self,
+        GLenum target, GLenum pname, const GLfloat* params)
+{
+    GLEncoder* ctx = (GLEncoder*)self;
+    const GLClientState* state = ctx->m_state;
+
+    SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
+            !isValidTextureExternalParam(pname, (GLenum)params[0])),
+            GL_INVALID_ENUM);
+
+    if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
+        ctx->override2DTextureTarget(target);
+        ctx->m_glTexParameterfv_enc(ctx, GL_TEXTURE_2D, pname, params);
+        ctx->restore2DTextureTarget();
+    } else {
+        ctx->m_glTexParameterfv_enc(ctx, target, pname, params);
+    }
+}
+
+void GLEncoder::s_glTexParameteri(void* self,
+        GLenum target, GLenum pname, GLint param)
+{
+    GLEncoder* ctx = (GLEncoder*)self;
+    const GLClientState* state = ctx->m_state;
+
+    SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
+            !isValidTextureExternalParam(pname, (GLenum)param)),
+            GL_INVALID_ENUM);
+
+    if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
+        ctx->override2DTextureTarget(target);
+        ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D, pname, param);
+        ctx->restore2DTextureTarget();
+    } else {
+        ctx->m_glTexParameteri_enc(ctx, target, pname, param);
+    }
+}
+
+void GLEncoder::s_glTexParameterx(void* self,
+        GLenum target, GLenum pname, GLfixed param)
+{
+    GLEncoder* ctx = (GLEncoder*)self;
+    const GLClientState* state = ctx->m_state;
+
+    SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
+            !isValidTextureExternalParam(pname, (GLenum)param)),
+            GL_INVALID_ENUM);
+
+    if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
+        ctx->override2DTextureTarget(target);
+        ctx->m_glTexParameterx_enc(ctx, GL_TEXTURE_2D, pname, param);
+        ctx->restore2DTextureTarget();
+    } else {
+        ctx->m_glTexParameterx_enc(ctx, target, pname, param);
+    }
+}
+
+void GLEncoder::s_glTexParameteriv(void* self,
+        GLenum target, GLenum pname, const GLint* params)
+{
+    GLEncoder* ctx = (GLEncoder*)self;
+    const GLClientState* state = ctx->m_state;
+
+    SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
+            !isValidTextureExternalParam(pname, (GLenum)params[0])),
+            GL_INVALID_ENUM);
+
+    if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
+        ctx->override2DTextureTarget(target);
+        ctx->m_glTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params);
+        ctx->restore2DTextureTarget();
+    } else {
+        ctx->m_glTexParameteriv_enc(ctx, target, pname, params);
+    }
+}
+
+void GLEncoder::s_glTexParameterxv(void* self,
+        GLenum target, GLenum pname, const GLfixed* params)
+{
+    GLEncoder* ctx = (GLEncoder*)self;
+    const GLClientState* state = ctx->m_state;
+
+    SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
+            !isValidTextureExternalParam(pname, (GLenum)params[0])),
+            GL_INVALID_ENUM);
+
+    if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
+        ctx->override2DTextureTarget(target);
+        ctx->m_glTexParameterxv_enc(ctx, GL_TEXTURE_2D, pname, params);
+        ctx->restore2DTextureTarget();
+    } else {
+        ctx->m_glTexParameterxv_enc(ctx, target, pname, params);
+    }
+}
+
+void GLEncoder::override2DTextureTarget(GLenum target)
+{
+    if ((target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) &&
+        target != m_state->getPriorityEnabledTarget(GL_TEXTURE_2D)) {
+            m_glBindTexture_enc(this, GL_TEXTURE_2D,
+                    m_state->getBoundTexture(target));
+    }
+}
+
+void GLEncoder::restore2DTextureTarget()
+{
+    GLenum priorityTarget = m_state->getPriorityEnabledTarget(GL_TEXTURE_2D);
+    m_glBindTexture_enc(this, GL_TEXTURE_2D,
+            m_state->getBoundTexture(priorityTarget));
+}
+
+GLEncoder::GLEncoder(IOStream *stream) : gl_encoder_context_t(stream)
+{
+    m_initialized = false;
+    m_state = NULL;
+    m_error = GL_NO_ERROR;
+    m_num_compressedTextureFormats = 0;
+    m_compressedTextureFormats = NULL;
+    // overrides;
+    m_glFlush_enc = set_glFlush(s_glFlush);
+    m_glPixelStorei_enc = set_glPixelStorei(s_glPixelStorei);
+    m_glVertexPointer_enc = set_glVertexPointer(s_glVertexPointer);
+    m_glNormalPointer_enc = set_glNormalPointer(s_glNormalPointer);
+    m_glColorPointer_enc = set_glColorPointer(s_glColorPointer);
+    m_glPointSizePointerOES_enc = set_glPointSizePointerOES(s_glPointsizePointer);
+    m_glClientActiveTexture_enc = set_glClientActiveTexture(s_glClientActiveTexture);
+    m_glTexCoordPointer_enc = set_glTexCoordPointer(s_glTexcoordPointer);
+    m_glMatrixIndexPointerOES_enc = set_glMatrixIndexPointerOES(s_glMatrixIndexPointerOES);
+    m_glWeightPointerOES_enc = set_glWeightPointerOES(s_glWeightPointerOES);
+
+    m_glGetIntegerv_enc = set_glGetIntegerv(s_glGetIntegerv);
+    m_glGetFloatv_enc = set_glGetFloatv(s_glGetFloatv);
+    m_glGetBooleanv_enc = set_glGetBooleanv(s_glGetBooleanv);
+    m_glGetFixedv_enc = set_glGetFixedv(s_glGetFixedv);
+    m_glGetPointerv_enc = set_glGetPointerv(s_glGetPointerv);
+
+    m_glBindBuffer_enc = set_glBindBuffer(s_glBindBuffer);
+    m_glBufferData_enc = set_glBufferData(s_glBufferData);
+    m_glBufferSubData_enc = set_glBufferSubData(s_glBufferSubData);
+    m_glDeleteBuffers_enc = set_glDeleteBuffers(s_glDeleteBuffers);
+
+    m_glEnableClientState_enc = set_glEnableClientState(s_glEnableClientState);
+    m_glDisableClientState_enc = set_glDisableClientState(s_glDisableClientState);
+    m_glIsEnabled_enc = set_glIsEnabled(s_glIsEnabled);
+    m_glDrawArrays_enc = set_glDrawArrays(s_glDrawArrays);
+    m_glDrawElements_enc = set_glDrawElements(s_glDrawElements);
+    set_glGetString(s_glGetString);
+    set_glFinish(s_glFinish);
+    m_glGetError_enc = set_glGetError(s_glGetError);
+
+    m_glActiveTexture_enc = set_glActiveTexture(s_glActiveTexture);
+    m_glBindTexture_enc = set_glBindTexture(s_glBindTexture);
+    m_glDeleteTextures_enc = set_glDeleteTextures(s_glDeleteTextures);
+    m_glDisable_enc = set_glDisable(s_glDisable);
+    m_glEnable_enc = set_glEnable(s_glEnable);
+    m_glGetTexParameterfv_enc = set_glGetTexParameterfv(s_glGetTexParameterfv);
+    m_glGetTexParameteriv_enc = set_glGetTexParameteriv(s_glGetTexParameteriv);
+    m_glGetTexParameterxv_enc = set_glGetTexParameterxv(s_glGetTexParameterxv);
+    m_glTexParameterf_enc = set_glTexParameterf(s_glTexParameterf);
+    m_glTexParameterfv_enc = set_glTexParameterfv(s_glTexParameterfv);
+    m_glTexParameteri_enc = set_glTexParameteri(s_glTexParameteri);
+    m_glTexParameterx_enc = set_glTexParameterx(s_glTexParameterx);
+    m_glTexParameteriv_enc = set_glTexParameteriv(s_glTexParameteriv);
+    m_glTexParameterxv_enc = set_glTexParameterxv(s_glTexParameterxv);
+}
+
+GLEncoder::~GLEncoder()
+{
+    delete [] m_compressedTextureFormats;
+}
+
+size_t GLEncoder::pixelDataSize(GLsizei width, GLsizei height, GLenum format, GLenum type, int pack)
+{
+    assert(m_state != NULL);
+    return m_state->pixelDataSize(width, height, format, type, pack);
+}
+
+void GLEncoder::s_glFinish(void *self)
+{
+    GLEncoder *ctx = (GLEncoder *)self;
+    ctx->glFinishRoundTrip(self);
+}
diff --git a/opengl/system/GLESv1_enc/GLEncoder.h b/opengl/system/GLESv1_enc/GLEncoder.h
new file mode 100644
index 0000000..effc53f
--- /dev/null
+++ b/opengl/system/GLESv1_enc/GLEncoder.h
@@ -0,0 +1,149 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#ifndef _GL_ENCODER_H_
+#define _GL_ENCODER_H_
+
+#include "gl_enc.h"
+#include "GLClientState.h"
+#include "GLSharedGroup.h"
+#include "FixedBuffer.h"
+
+class GLEncoder : public gl_encoder_context_t {
+
+public:
+    GLEncoder(IOStream *stream);
+    virtual ~GLEncoder();
+    void setClientState(GLClientState *state) {
+        m_state = state;
+    }
+    void setSharedGroup(GLSharedGroupPtr shared) { m_shared = shared; }
+    void flush() { m_stream->flush(); }
+    size_t pixelDataSize(GLsizei width, GLsizei height, GLenum format, GLenum type, int pack);
+
+    void setInitialized(){ m_initialized = true; };
+    bool isInitialized(){ return m_initialized; };
+
+    virtual void setError(GLenum error){ m_error = error; };
+    virtual GLenum getError() { return m_error; };
+
+    void override2DTextureTarget(GLenum target);
+    void restore2DTextureTarget();
+
+private:
+
+    bool    m_initialized;
+    GLClientState *m_state;
+    GLSharedGroupPtr m_shared;
+    GLenum  m_error;
+    FixedBuffer m_fixedBuffer;
+    GLint *m_compressedTextureFormats;
+    GLint m_num_compressedTextureFormats;
+
+    GLint *getCompressedTextureFormats();
+    // original functions;
+    glGetError_client_proc_t    m_glGetError_enc;
+    glGetIntegerv_client_proc_t m_glGetIntegerv_enc;
+    glGetFloatv_client_proc_t m_glGetFloatv_enc;
+    glGetFixedv_client_proc_t m_glGetFixedv_enc;
+    glGetBooleanv_client_proc_t m_glGetBooleanv_enc;
+    glGetPointerv_client_proc_t m_glGetPointerv_enc;
+
+    glPixelStorei_client_proc_t m_glPixelStorei_enc;
+    glVertexPointer_client_proc_t m_glVertexPointer_enc;
+    glNormalPointer_client_proc_t m_glNormalPointer_enc;
+    glColorPointer_client_proc_t m_glColorPointer_enc;
+    glPointSizePointerOES_client_proc_t m_glPointSizePointerOES_enc;
+    glTexCoordPointer_client_proc_t m_glTexCoordPointer_enc;
+    glClientActiveTexture_client_proc_t m_glClientActiveTexture_enc;
+    glMatrixIndexPointerOES_client_proc_t m_glMatrixIndexPointerOES_enc;
+    glWeightPointerOES_client_proc_t m_glWeightPointerOES_enc;
+
+    glBindBuffer_client_proc_t m_glBindBuffer_enc;
+    glBufferData_client_proc_t m_glBufferData_enc;
+    glBufferSubData_client_proc_t m_glBufferSubData_enc;
+    glDeleteBuffers_client_proc_t m_glDeleteBuffers_enc;
+    
+    glEnableClientState_client_proc_t m_glEnableClientState_enc;
+    glDisableClientState_client_proc_t m_glDisableClientState_enc;
+    glIsEnabled_client_proc_t m_glIsEnabled_enc;
+    glDrawArrays_client_proc_t m_glDrawArrays_enc;
+    glDrawElements_client_proc_t m_glDrawElements_enc;
+    glFlush_client_proc_t m_glFlush_enc;
+
+    glActiveTexture_client_proc_t m_glActiveTexture_enc;
+    glBindTexture_client_proc_t m_glBindTexture_enc;
+    glDeleteTextures_client_proc_t m_glDeleteTextures_enc;
+    glDisable_client_proc_t m_glDisable_enc;
+    glEnable_client_proc_t m_glEnable_enc;
+    glGetTexParameterfv_client_proc_t m_glGetTexParameterfv_enc;
+    glGetTexParameteriv_client_proc_t m_glGetTexParameteriv_enc;
+    glGetTexParameterxv_client_proc_t m_glGetTexParameterxv_enc;
+    glTexParameterf_client_proc_t m_glTexParameterf_enc;
+    glTexParameterfv_client_proc_t m_glTexParameterfv_enc;
+    glTexParameteri_client_proc_t m_glTexParameteri_enc;
+    glTexParameterx_client_proc_t m_glTexParameterx_enc;
+    glTexParameteriv_client_proc_t m_glTexParameteriv_enc;
+    glTexParameterxv_client_proc_t m_glTexParameterxv_enc;
+
+    // statics
+    static GLenum s_glGetError(void * self);
+    static void s_glGetIntegerv(void *self, GLenum pname, GLint *ptr);
+    static void s_glGetBooleanv(void *self, GLenum pname, GLboolean *ptr);
+    static void s_glGetFloatv(void *self, GLenum pname, GLfloat *ptr);
+    static void s_glGetFixedv(void *self, GLenum pname, GLfixed *ptr);
+    static void s_glGetPointerv(void *self, GLenum pname, GLvoid **params);
+
+    static void s_glFlush(void * self);
+    static const GLubyte * s_glGetString(void *self, GLenum name);
+    static void s_glVertexPointer(void *self, int size, GLenum type, GLsizei stride, const void *data);
+    static void s_glNormalPointer(void *self, GLenum type, GLsizei stride, const void *data);
+    static void s_glColorPointer(void *self, int size, GLenum type, GLsizei stride, const void *data);
+    static void s_glPointsizePointer(void *self, GLenum type, GLsizei stride, const void *data);
+    static void s_glClientActiveTexture(void *self, GLenum texture);
+    static void s_glTexcoordPointer(void *self, int size, GLenum type, GLsizei stride, const void *data);
+    static void s_glMatrixIndexPointerOES(void *self, int size, GLenum type, GLsizei stride, const void * data);
+    static void s_glWeightPointerOES(void *self, int size, GLenum type, GLsizei stride, const void * data);
+    static void s_glDisableClientState(void *self, GLenum state);
+    static void s_glEnableClientState(void *self, GLenum state);
+    static GLboolean s_glIsEnabled(void *self, GLenum cap);
+    static void s_glBindBuffer(void *self, GLenum target, GLuint id);
+    static void s_glBufferData(void *self, GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage);
+    static void s_glBufferSubData(void *self, GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data);
+    static void s_glDeleteBuffers(void *self, GLsizei n, const GLuint * buffers);
+
+    static void s_glDrawArrays(void *self, GLenum mode, GLint first, GLsizei count);
+    static void s_glDrawElements(void *self, GLenum mode, GLsizei count, GLenum type, const void *indices);
+    static void s_glPixelStorei(void *self, GLenum param, GLint value);
+
+    static void s_glFinish(void *self);
+    void sendVertexData(unsigned first, unsigned count);
+
+    static void s_glActiveTexture(void* self, GLenum texture);
+    static void s_glBindTexture(void* self, GLenum target, GLuint texture);
+    static void s_glDeleteTextures(void* self, GLsizei n, const GLuint* textures);
+    static void s_glDisable(void* self, GLenum cap);
+    static void s_glEnable(void* self, GLenum cap);
+    static void s_glGetTexParameterfv(void* self, GLenum target, GLenum pname, GLfloat* params);
+    static void s_glGetTexParameteriv(void* self, GLenum target, GLenum pname, GLint* params);
+    static void s_glGetTexParameterxv(void* self, GLenum target, GLenum pname, GLfixed* params);
+    static void s_glTexParameterf(void* self, GLenum target, GLenum pname, GLfloat param);
+    static void s_glTexParameterfv(void* self, GLenum target, GLenum pname, const GLfloat* params);
+    static void s_glTexParameteri(void* self, GLenum target, GLenum pname, GLint param);
+    static void s_glTexParameterx(void* self, GLenum target, GLenum pname, GLfixed param);
+    static void s_glTexParameteriv(void* self, GLenum target, GLenum pname, const GLint* params);
+    static void s_glTexParameterxv(void* self, GLenum target, GLenum pname, const GLfixed* params);
+};
+#endif
diff --git a/opengl/system/GLESv1_enc/GLEncoderUtils.cpp b/opengl/system/GLESv1_enc/GLEncoderUtils.cpp
new file mode 100644
index 0000000..7866d53
--- /dev/null
+++ b/opengl/system/GLESv1_enc/GLEncoderUtils.cpp
@@ -0,0 +1,24 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include "GLEncoder.h"
+
+size_t pixelDataSize(void *self, GLsizei width, GLsizei height, GLenum format, GLenum type, int pack)
+{
+    GLEncoder *ctx = (GLEncoder *)self;
+    return ctx->pixelDataSize(width, height, format, type, pack);
+}
diff --git a/opengl/system/GLESv1_enc/GLEncoderUtils.h b/opengl/system/GLESv1_enc/GLEncoderUtils.h
new file mode 100644
index 0000000..1d0c847
--- /dev/null
+++ b/opengl/system/GLESv1_enc/GLEncoderUtils.h
@@ -0,0 +1,22 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#ifndef GL_ENCODER_UTILS_H
+#define GL_ENCLODER_UTILS_H
+
+extern "C" {
+    size_t pixelDataSize(void *self, GLsizei width, GLsizei height, GLenum format, GLenum type, int pack);
+};
+#endif
diff --git a/opengl/system/GLESv1_enc/gl_client_context.cpp b/opengl/system/GLESv1_enc/gl_client_context.cpp
new file mode 100644
index 0000000..a5fd04b
--- /dev/null
+++ b/opengl/system/GLESv1_enc/gl_client_context.cpp
@@ -0,0 +1,308 @@
+// Generated Code - DO NOT EDIT !!
+// generated by 'emugen'
+
+
+#include <string.h>
+#include "gl_client_context.h"
+
+
+#include <stdio.h>
+
+int gl_client_context_t::initDispatchByName(void *(*getProc)(const char *, void *userData), void *userData)
+{
+	void *ptr;
+
+	ptr = getProc("glAlphaFunc", userData); set_glAlphaFunc((glAlphaFunc_client_proc_t)ptr);
+	ptr = getProc("glClearColor", userData); set_glClearColor((glClearColor_client_proc_t)ptr);
+	ptr = getProc("glClearDepthf", userData); set_glClearDepthf((glClearDepthf_client_proc_t)ptr);
+	ptr = getProc("glClipPlanef", userData); set_glClipPlanef((glClipPlanef_client_proc_t)ptr);
+	ptr = getProc("glColor4f", userData); set_glColor4f((glColor4f_client_proc_t)ptr);
+	ptr = getProc("glDepthRangef", userData); set_glDepthRangef((glDepthRangef_client_proc_t)ptr);
+	ptr = getProc("glFogf", userData); set_glFogf((glFogf_client_proc_t)ptr);
+	ptr = getProc("glFogfv", userData); set_glFogfv((glFogfv_client_proc_t)ptr);
+	ptr = getProc("glFrustumf", userData); set_glFrustumf((glFrustumf_client_proc_t)ptr);
+	ptr = getProc("glGetClipPlanef", userData); set_glGetClipPlanef((glGetClipPlanef_client_proc_t)ptr);
+	ptr = getProc("glGetFloatv", userData); set_glGetFloatv((glGetFloatv_client_proc_t)ptr);
+	ptr = getProc("glGetLightfv", userData); set_glGetLightfv((glGetLightfv_client_proc_t)ptr);
+	ptr = getProc("glGetMaterialfv", userData); set_glGetMaterialfv((glGetMaterialfv_client_proc_t)ptr);
+	ptr = getProc("glGetTexEnvfv", userData); set_glGetTexEnvfv((glGetTexEnvfv_client_proc_t)ptr);
+	ptr = getProc("glGetTexParameterfv", userData); set_glGetTexParameterfv((glGetTexParameterfv_client_proc_t)ptr);
+	ptr = getProc("glLightModelf", userData); set_glLightModelf((glLightModelf_client_proc_t)ptr);
+	ptr = getProc("glLightModelfv", userData); set_glLightModelfv((glLightModelfv_client_proc_t)ptr);
+	ptr = getProc("glLightf", userData); set_glLightf((glLightf_client_proc_t)ptr);
+	ptr = getProc("glLightfv", userData); set_glLightfv((glLightfv_client_proc_t)ptr);
+	ptr = getProc("glLineWidth", userData); set_glLineWidth((glLineWidth_client_proc_t)ptr);
+	ptr = getProc("glLoadMatrixf", userData); set_glLoadMatrixf((glLoadMatrixf_client_proc_t)ptr);
+	ptr = getProc("glMaterialf", userData); set_glMaterialf((glMaterialf_client_proc_t)ptr);
+	ptr = getProc("glMaterialfv", userData); set_glMaterialfv((glMaterialfv_client_proc_t)ptr);
+	ptr = getProc("glMultMatrixf", userData); set_glMultMatrixf((glMultMatrixf_client_proc_t)ptr);
+	ptr = getProc("glMultiTexCoord4f", userData); set_glMultiTexCoord4f((glMultiTexCoord4f_client_proc_t)ptr);
+	ptr = getProc("glNormal3f", userData); set_glNormal3f((glNormal3f_client_proc_t)ptr);
+	ptr = getProc("glOrthof", userData); set_glOrthof((glOrthof_client_proc_t)ptr);
+	ptr = getProc("glPointParameterf", userData); set_glPointParameterf((glPointParameterf_client_proc_t)ptr);
+	ptr = getProc("glPointParameterfv", userData); set_glPointParameterfv((glPointParameterfv_client_proc_t)ptr);
+	ptr = getProc("glPointSize", userData); set_glPointSize((glPointSize_client_proc_t)ptr);
+	ptr = getProc("glPolygonOffset", userData); set_glPolygonOffset((glPolygonOffset_client_proc_t)ptr);
+	ptr = getProc("glRotatef", userData); set_glRotatef((glRotatef_client_proc_t)ptr);
+	ptr = getProc("glScalef", userData); set_glScalef((glScalef_client_proc_t)ptr);
+	ptr = getProc("glTexEnvf", userData); set_glTexEnvf((glTexEnvf_client_proc_t)ptr);
+	ptr = getProc("glTexEnvfv", userData); set_glTexEnvfv((glTexEnvfv_client_proc_t)ptr);
+	ptr = getProc("glTexParameterf", userData); set_glTexParameterf((glTexParameterf_client_proc_t)ptr);
+	ptr = getProc("glTexParameterfv", userData); set_glTexParameterfv((glTexParameterfv_client_proc_t)ptr);
+	ptr = getProc("glTranslatef", userData); set_glTranslatef((glTranslatef_client_proc_t)ptr);
+	ptr = getProc("glActiveTexture", userData); set_glActiveTexture((glActiveTexture_client_proc_t)ptr);
+	ptr = getProc("glAlphaFuncx", userData); set_glAlphaFuncx((glAlphaFuncx_client_proc_t)ptr);
+	ptr = getProc("glBindBuffer", userData); set_glBindBuffer((glBindBuffer_client_proc_t)ptr);
+	ptr = getProc("glBindTexture", userData); set_glBindTexture((glBindTexture_client_proc_t)ptr);
+	ptr = getProc("glBlendFunc", userData); set_glBlendFunc((glBlendFunc_client_proc_t)ptr);
+	ptr = getProc("glBufferData", userData); set_glBufferData((glBufferData_client_proc_t)ptr);
+	ptr = getProc("glBufferSubData", userData); set_glBufferSubData((glBufferSubData_client_proc_t)ptr);
+	ptr = getProc("glClear", userData); set_glClear((glClear_client_proc_t)ptr);
+	ptr = getProc("glClearColorx", userData); set_glClearColorx((glClearColorx_client_proc_t)ptr);
+	ptr = getProc("glClearDepthx", userData); set_glClearDepthx((glClearDepthx_client_proc_t)ptr);
+	ptr = getProc("glClearStencil", userData); set_glClearStencil((glClearStencil_client_proc_t)ptr);
+	ptr = getProc("glClientActiveTexture", userData); set_glClientActiveTexture((glClientActiveTexture_client_proc_t)ptr);
+	ptr = getProc("glColor4ub", userData); set_glColor4ub((glColor4ub_client_proc_t)ptr);
+	ptr = getProc("glColor4x", userData); set_glColor4x((glColor4x_client_proc_t)ptr);
+	ptr = getProc("glColorMask", userData); set_glColorMask((glColorMask_client_proc_t)ptr);
+	ptr = getProc("glColorPointer", userData); set_glColorPointer((glColorPointer_client_proc_t)ptr);
+	ptr = getProc("glCompressedTexImage2D", userData); set_glCompressedTexImage2D((glCompressedTexImage2D_client_proc_t)ptr);
+	ptr = getProc("glCompressedTexSubImage2D", userData); set_glCompressedTexSubImage2D((glCompressedTexSubImage2D_client_proc_t)ptr);
+	ptr = getProc("glCopyTexImage2D", userData); set_glCopyTexImage2D((glCopyTexImage2D_client_proc_t)ptr);
+	ptr = getProc("glCopyTexSubImage2D", userData); set_glCopyTexSubImage2D((glCopyTexSubImage2D_client_proc_t)ptr);
+	ptr = getProc("glCullFace", userData); set_glCullFace((glCullFace_client_proc_t)ptr);
+	ptr = getProc("glDeleteBuffers", userData); set_glDeleteBuffers((glDeleteBuffers_client_proc_t)ptr);
+	ptr = getProc("glDeleteTextures", userData); set_glDeleteTextures((glDeleteTextures_client_proc_t)ptr);
+	ptr = getProc("glDepthFunc", userData); set_glDepthFunc((glDepthFunc_client_proc_t)ptr);
+	ptr = getProc("glDepthMask", userData); set_glDepthMask((glDepthMask_client_proc_t)ptr);
+	ptr = getProc("glDepthRangex", userData); set_glDepthRangex((glDepthRangex_client_proc_t)ptr);
+	ptr = getProc("glDisable", userData); set_glDisable((glDisable_client_proc_t)ptr);
+	ptr = getProc("glDisableClientState", userData); set_glDisableClientState((glDisableClientState_client_proc_t)ptr);
+	ptr = getProc("glDrawArrays", userData); set_glDrawArrays((glDrawArrays_client_proc_t)ptr);
+	ptr = getProc("glDrawElements", userData); set_glDrawElements((glDrawElements_client_proc_t)ptr);
+	ptr = getProc("glEnable", userData); set_glEnable((glEnable_client_proc_t)ptr);
+	ptr = getProc("glEnableClientState", userData); set_glEnableClientState((glEnableClientState_client_proc_t)ptr);
+	ptr = getProc("glFinish", userData); set_glFinish((glFinish_client_proc_t)ptr);
+	ptr = getProc("glFlush", userData); set_glFlush((glFlush_client_proc_t)ptr);
+	ptr = getProc("glFogx", userData); set_glFogx((glFogx_client_proc_t)ptr);
+	ptr = getProc("glFogxv", userData); set_glFogxv((glFogxv_client_proc_t)ptr);
+	ptr = getProc("glFrontFace", userData); set_glFrontFace((glFrontFace_client_proc_t)ptr);
+	ptr = getProc("glFrustumx", userData); set_glFrustumx((glFrustumx_client_proc_t)ptr);
+	ptr = getProc("glGetBooleanv", userData); set_glGetBooleanv((glGetBooleanv_client_proc_t)ptr);
+	ptr = getProc("glGetBufferParameteriv", userData); set_glGetBufferParameteriv((glGetBufferParameteriv_client_proc_t)ptr);
+	ptr = getProc("glClipPlanex", userData); set_glClipPlanex((glClipPlanex_client_proc_t)ptr);
+	ptr = getProc("glGenBuffers", userData); set_glGenBuffers((glGenBuffers_client_proc_t)ptr);
+	ptr = getProc("glGenTextures", userData); set_glGenTextures((glGenTextures_client_proc_t)ptr);
+	ptr = getProc("glGetError", userData); set_glGetError((glGetError_client_proc_t)ptr);
+	ptr = getProc("glGetFixedv", userData); set_glGetFixedv((glGetFixedv_client_proc_t)ptr);
+	ptr = getProc("glGetIntegerv", userData); set_glGetIntegerv((glGetIntegerv_client_proc_t)ptr);
+	ptr = getProc("glGetLightxv", userData); set_glGetLightxv((glGetLightxv_client_proc_t)ptr);
+	ptr = getProc("glGetMaterialxv", userData); set_glGetMaterialxv((glGetMaterialxv_client_proc_t)ptr);
+	ptr = getProc("glGetPointerv", userData); set_glGetPointerv((glGetPointerv_client_proc_t)ptr);
+	ptr = getProc("glGetString", userData); set_glGetString((glGetString_client_proc_t)ptr);
+	ptr = getProc("glGetTexEnviv", userData); set_glGetTexEnviv((glGetTexEnviv_client_proc_t)ptr);
+	ptr = getProc("glGetTexEnvxv", userData); set_glGetTexEnvxv((glGetTexEnvxv_client_proc_t)ptr);
+	ptr = getProc("glGetTexParameteriv", userData); set_glGetTexParameteriv((glGetTexParameteriv_client_proc_t)ptr);
+	ptr = getProc("glGetTexParameterxv", userData); set_glGetTexParameterxv((glGetTexParameterxv_client_proc_t)ptr);
+	ptr = getProc("glHint", userData); set_glHint((glHint_client_proc_t)ptr);
+	ptr = getProc("glIsBuffer", userData); set_glIsBuffer((glIsBuffer_client_proc_t)ptr);
+	ptr = getProc("glIsEnabled", userData); set_glIsEnabled((glIsEnabled_client_proc_t)ptr);
+	ptr = getProc("glIsTexture", userData); set_glIsTexture((glIsTexture_client_proc_t)ptr);
+	ptr = getProc("glLightModelx", userData); set_glLightModelx((glLightModelx_client_proc_t)ptr);
+	ptr = getProc("glLightModelxv", userData); set_glLightModelxv((glLightModelxv_client_proc_t)ptr);
+	ptr = getProc("glLightx", userData); set_glLightx((glLightx_client_proc_t)ptr);
+	ptr = getProc("glLightxv", userData); set_glLightxv((glLightxv_client_proc_t)ptr);
+	ptr = getProc("glLineWidthx", userData); set_glLineWidthx((glLineWidthx_client_proc_t)ptr);
+	ptr = getProc("glLoadIdentity", userData); set_glLoadIdentity((glLoadIdentity_client_proc_t)ptr);
+	ptr = getProc("glLoadMatrixx", userData); set_glLoadMatrixx((glLoadMatrixx_client_proc_t)ptr);
+	ptr = getProc("glLogicOp", userData); set_glLogicOp((glLogicOp_client_proc_t)ptr);
+	ptr = getProc("glMaterialx", userData); set_glMaterialx((glMaterialx_client_proc_t)ptr);
+	ptr = getProc("glMaterialxv", userData); set_glMaterialxv((glMaterialxv_client_proc_t)ptr);
+	ptr = getProc("glMatrixMode", userData); set_glMatrixMode((glMatrixMode_client_proc_t)ptr);
+	ptr = getProc("glMultMatrixx", userData); set_glMultMatrixx((glMultMatrixx_client_proc_t)ptr);
+	ptr = getProc("glMultiTexCoord4x", userData); set_glMultiTexCoord4x((glMultiTexCoord4x_client_proc_t)ptr);
+	ptr = getProc("glNormal3x", userData); set_glNormal3x((glNormal3x_client_proc_t)ptr);
+	ptr = getProc("glNormalPointer", userData); set_glNormalPointer((glNormalPointer_client_proc_t)ptr);
+	ptr = getProc("glOrthox", userData); set_glOrthox((glOrthox_client_proc_t)ptr);
+	ptr = getProc("glPixelStorei", userData); set_glPixelStorei((glPixelStorei_client_proc_t)ptr);
+	ptr = getProc("glPointParameterx", userData); set_glPointParameterx((glPointParameterx_client_proc_t)ptr);
+	ptr = getProc("glPointParameterxv", userData); set_glPointParameterxv((glPointParameterxv_client_proc_t)ptr);
+	ptr = getProc("glPointSizex", userData); set_glPointSizex((glPointSizex_client_proc_t)ptr);
+	ptr = getProc("glPolygonOffsetx", userData); set_glPolygonOffsetx((glPolygonOffsetx_client_proc_t)ptr);
+	ptr = getProc("glPopMatrix", userData); set_glPopMatrix((glPopMatrix_client_proc_t)ptr);
+	ptr = getProc("glPushMatrix", userData); set_glPushMatrix((glPushMatrix_client_proc_t)ptr);
+	ptr = getProc("glReadPixels", userData); set_glReadPixels((glReadPixels_client_proc_t)ptr);
+	ptr = getProc("glRotatex", userData); set_glRotatex((glRotatex_client_proc_t)ptr);
+	ptr = getProc("glSampleCoverage", userData); set_glSampleCoverage((glSampleCoverage_client_proc_t)ptr);
+	ptr = getProc("glSampleCoveragex", userData); set_glSampleCoveragex((glSampleCoveragex_client_proc_t)ptr);
+	ptr = getProc("glScalex", userData); set_glScalex((glScalex_client_proc_t)ptr);
+	ptr = getProc("glScissor", userData); set_glScissor((glScissor_client_proc_t)ptr);
+	ptr = getProc("glShadeModel", userData); set_glShadeModel((glShadeModel_client_proc_t)ptr);
+	ptr = getProc("glStencilFunc", userData); set_glStencilFunc((glStencilFunc_client_proc_t)ptr);
+	ptr = getProc("glStencilMask", userData); set_glStencilMask((glStencilMask_client_proc_t)ptr);
+	ptr = getProc("glStencilOp", userData); set_glStencilOp((glStencilOp_client_proc_t)ptr);
+	ptr = getProc("glTexCoordPointer", userData); set_glTexCoordPointer((glTexCoordPointer_client_proc_t)ptr);
+	ptr = getProc("glTexEnvi", userData); set_glTexEnvi((glTexEnvi_client_proc_t)ptr);
+	ptr = getProc("glTexEnvx", userData); set_glTexEnvx((glTexEnvx_client_proc_t)ptr);
+	ptr = getProc("glTexEnviv", userData); set_glTexEnviv((glTexEnviv_client_proc_t)ptr);
+	ptr = getProc("glTexEnvxv", userData); set_glTexEnvxv((glTexEnvxv_client_proc_t)ptr);
+	ptr = getProc("glTexImage2D", userData); set_glTexImage2D((glTexImage2D_client_proc_t)ptr);
+	ptr = getProc("glTexParameteri", userData); set_glTexParameteri((glTexParameteri_client_proc_t)ptr);
+	ptr = getProc("glTexParameterx", userData); set_glTexParameterx((glTexParameterx_client_proc_t)ptr);
+	ptr = getProc("glTexParameteriv", userData); set_glTexParameteriv((glTexParameteriv_client_proc_t)ptr);
+	ptr = getProc("glTexParameterxv", userData); set_glTexParameterxv((glTexParameterxv_client_proc_t)ptr);
+	ptr = getProc("glTexSubImage2D", userData); set_glTexSubImage2D((glTexSubImage2D_client_proc_t)ptr);
+	ptr = getProc("glTranslatex", userData); set_glTranslatex((glTranslatex_client_proc_t)ptr);
+	ptr = getProc("glVertexPointer", userData); set_glVertexPointer((glVertexPointer_client_proc_t)ptr);
+	ptr = getProc("glViewport", userData); set_glViewport((glViewport_client_proc_t)ptr);
+	ptr = getProc("glPointSizePointerOES", userData); set_glPointSizePointerOES((glPointSizePointerOES_client_proc_t)ptr);
+	ptr = getProc("glVertexPointerOffset", userData); set_glVertexPointerOffset((glVertexPointerOffset_client_proc_t)ptr);
+	ptr = getProc("glColorPointerOffset", userData); set_glColorPointerOffset((glColorPointerOffset_client_proc_t)ptr);
+	ptr = getProc("glNormalPointerOffset", userData); set_glNormalPointerOffset((glNormalPointerOffset_client_proc_t)ptr);
+	ptr = getProc("glPointSizePointerOffset", userData); set_glPointSizePointerOffset((glPointSizePointerOffset_client_proc_t)ptr);
+	ptr = getProc("glTexCoordPointerOffset", userData); set_glTexCoordPointerOffset((glTexCoordPointerOffset_client_proc_t)ptr);
+	ptr = getProc("glWeightPointerOffset", userData); set_glWeightPointerOffset((glWeightPointerOffset_client_proc_t)ptr);
+	ptr = getProc("glMatrixIndexPointerOffset", userData); set_glMatrixIndexPointerOffset((glMatrixIndexPointerOffset_client_proc_t)ptr);
+	ptr = getProc("glVertexPointerData", userData); set_glVertexPointerData((glVertexPointerData_client_proc_t)ptr);
+	ptr = getProc("glColorPointerData", userData); set_glColorPointerData((glColorPointerData_client_proc_t)ptr);
+	ptr = getProc("glNormalPointerData", userData); set_glNormalPointerData((glNormalPointerData_client_proc_t)ptr);
+	ptr = getProc("glTexCoordPointerData", userData); set_glTexCoordPointerData((glTexCoordPointerData_client_proc_t)ptr);
+	ptr = getProc("glPointSizePointerData", userData); set_glPointSizePointerData((glPointSizePointerData_client_proc_t)ptr);
+	ptr = getProc("glWeightPointerData", userData); set_glWeightPointerData((glWeightPointerData_client_proc_t)ptr);
+	ptr = getProc("glMatrixIndexPointerData", userData); set_glMatrixIndexPointerData((glMatrixIndexPointerData_client_proc_t)ptr);
+	ptr = getProc("glDrawElementsOffset", userData); set_glDrawElementsOffset((glDrawElementsOffset_client_proc_t)ptr);
+	ptr = getProc("glDrawElementsData", userData); set_glDrawElementsData((glDrawElementsData_client_proc_t)ptr);
+	ptr = getProc("glGetCompressedTextureFormats", userData); set_glGetCompressedTextureFormats((glGetCompressedTextureFormats_client_proc_t)ptr);
+	ptr = getProc("glFinishRoundTrip", userData); set_glFinishRoundTrip((glFinishRoundTrip_client_proc_t)ptr);
+	ptr = getProc("glBlendEquationSeparateOES", userData); set_glBlendEquationSeparateOES((glBlendEquationSeparateOES_client_proc_t)ptr);
+	ptr = getProc("glBlendFuncSeparateOES", userData); set_glBlendFuncSeparateOES((glBlendFuncSeparateOES_client_proc_t)ptr);
+	ptr = getProc("glBlendEquationOES", userData); set_glBlendEquationOES((glBlendEquationOES_client_proc_t)ptr);
+	ptr = getProc("glDrawTexsOES", userData); set_glDrawTexsOES((glDrawTexsOES_client_proc_t)ptr);
+	ptr = getProc("glDrawTexiOES", userData); set_glDrawTexiOES((glDrawTexiOES_client_proc_t)ptr);
+	ptr = getProc("glDrawTexxOES", userData); set_glDrawTexxOES((glDrawTexxOES_client_proc_t)ptr);
+	ptr = getProc("glDrawTexsvOES", userData); set_glDrawTexsvOES((glDrawTexsvOES_client_proc_t)ptr);
+	ptr = getProc("glDrawTexivOES", userData); set_glDrawTexivOES((glDrawTexivOES_client_proc_t)ptr);
+	ptr = getProc("glDrawTexxvOES", userData); set_glDrawTexxvOES((glDrawTexxvOES_client_proc_t)ptr);
+	ptr = getProc("glDrawTexfOES", userData); set_glDrawTexfOES((glDrawTexfOES_client_proc_t)ptr);
+	ptr = getProc("glDrawTexfvOES", userData); set_glDrawTexfvOES((glDrawTexfvOES_client_proc_t)ptr);
+	ptr = getProc("glEGLImageTargetTexture2DOES", userData); set_glEGLImageTargetTexture2DOES((glEGLImageTargetTexture2DOES_client_proc_t)ptr);
+	ptr = getProc("glEGLImageTargetRenderbufferStorageOES", userData); set_glEGLImageTargetRenderbufferStorageOES((glEGLImageTargetRenderbufferStorageOES_client_proc_t)ptr);
+	ptr = getProc("glAlphaFuncxOES", userData); set_glAlphaFuncxOES((glAlphaFuncxOES_client_proc_t)ptr);
+	ptr = getProc("glClearColorxOES", userData); set_glClearColorxOES((glClearColorxOES_client_proc_t)ptr);
+	ptr = getProc("glClearDepthxOES", userData); set_glClearDepthxOES((glClearDepthxOES_client_proc_t)ptr);
+	ptr = getProc("glClipPlanexOES", userData); set_glClipPlanexOES((glClipPlanexOES_client_proc_t)ptr);
+	ptr = getProc("glClipPlanexIMG", userData); set_glClipPlanexIMG((glClipPlanexIMG_client_proc_t)ptr);
+	ptr = getProc("glColor4xOES", userData); set_glColor4xOES((glColor4xOES_client_proc_t)ptr);
+	ptr = getProc("glDepthRangexOES", userData); set_glDepthRangexOES((glDepthRangexOES_client_proc_t)ptr);
+	ptr = getProc("glFogxOES", userData); set_glFogxOES((glFogxOES_client_proc_t)ptr);
+	ptr = getProc("glFogxvOES", userData); set_glFogxvOES((glFogxvOES_client_proc_t)ptr);
+	ptr = getProc("glFrustumxOES", userData); set_glFrustumxOES((glFrustumxOES_client_proc_t)ptr);
+	ptr = getProc("glGetClipPlanexOES", userData); set_glGetClipPlanexOES((glGetClipPlanexOES_client_proc_t)ptr);
+	ptr = getProc("glGetClipPlanex", userData); set_glGetClipPlanex((glGetClipPlanex_client_proc_t)ptr);
+	ptr = getProc("glGetFixedvOES", userData); set_glGetFixedvOES((glGetFixedvOES_client_proc_t)ptr);
+	ptr = getProc("glGetLightxvOES", userData); set_glGetLightxvOES((glGetLightxvOES_client_proc_t)ptr);
+	ptr = getProc("glGetMaterialxvOES", userData); set_glGetMaterialxvOES((glGetMaterialxvOES_client_proc_t)ptr);
+	ptr = getProc("glGetTexEnvxvOES", userData); set_glGetTexEnvxvOES((glGetTexEnvxvOES_client_proc_t)ptr);
+	ptr = getProc("glGetTexParameterxvOES", userData); set_glGetTexParameterxvOES((glGetTexParameterxvOES_client_proc_t)ptr);
+	ptr = getProc("glLightModelxOES", userData); set_glLightModelxOES((glLightModelxOES_client_proc_t)ptr);
+	ptr = getProc("glLightModelxvOES", userData); set_glLightModelxvOES((glLightModelxvOES_client_proc_t)ptr);
+	ptr = getProc("glLightxOES", userData); set_glLightxOES((glLightxOES_client_proc_t)ptr);
+	ptr = getProc("glLightxvOES", userData); set_glLightxvOES((glLightxvOES_client_proc_t)ptr);
+	ptr = getProc("glLineWidthxOES", userData); set_glLineWidthxOES((glLineWidthxOES_client_proc_t)ptr);
+	ptr = getProc("glLoadMatrixxOES", userData); set_glLoadMatrixxOES((glLoadMatrixxOES_client_proc_t)ptr);
+	ptr = getProc("glMaterialxOES", userData); set_glMaterialxOES((glMaterialxOES_client_proc_t)ptr);
+	ptr = getProc("glMaterialxvOES", userData); set_glMaterialxvOES((glMaterialxvOES_client_proc_t)ptr);
+	ptr = getProc("glMultMatrixxOES", userData); set_glMultMatrixxOES((glMultMatrixxOES_client_proc_t)ptr);
+	ptr = getProc("glMultiTexCoord4xOES", userData); set_glMultiTexCoord4xOES((glMultiTexCoord4xOES_client_proc_t)ptr);
+	ptr = getProc("glNormal3xOES", userData); set_glNormal3xOES((glNormal3xOES_client_proc_t)ptr);
+	ptr = getProc("glOrthoxOES", userData); set_glOrthoxOES((glOrthoxOES_client_proc_t)ptr);
+	ptr = getProc("glPointParameterxOES", userData); set_glPointParameterxOES((glPointParameterxOES_client_proc_t)ptr);
+	ptr = getProc("glPointParameterxvOES", userData); set_glPointParameterxvOES((glPointParameterxvOES_client_proc_t)ptr);
+	ptr = getProc("glPointSizexOES", userData); set_glPointSizexOES((glPointSizexOES_client_proc_t)ptr);
+	ptr = getProc("glPolygonOffsetxOES", userData); set_glPolygonOffsetxOES((glPolygonOffsetxOES_client_proc_t)ptr);
+	ptr = getProc("glRotatexOES", userData); set_glRotatexOES((glRotatexOES_client_proc_t)ptr);
+	ptr = getProc("glSampleCoveragexOES", userData); set_glSampleCoveragexOES((glSampleCoveragexOES_client_proc_t)ptr);
+	ptr = getProc("glScalexOES", userData); set_glScalexOES((glScalexOES_client_proc_t)ptr);
+	ptr = getProc("glTexEnvxOES", userData); set_glTexEnvxOES((glTexEnvxOES_client_proc_t)ptr);
+	ptr = getProc("glTexEnvxvOES", userData); set_glTexEnvxvOES((glTexEnvxvOES_client_proc_t)ptr);
+	ptr = getProc("glTexParameterxOES", userData); set_glTexParameterxOES((glTexParameterxOES_client_proc_t)ptr);
+	ptr = getProc("glTexParameterxvOES", userData); set_glTexParameterxvOES((glTexParameterxvOES_client_proc_t)ptr);
+	ptr = getProc("glTranslatexOES", userData); set_glTranslatexOES((glTranslatexOES_client_proc_t)ptr);
+	ptr = getProc("glIsRenderbufferOES", userData); set_glIsRenderbufferOES((glIsRenderbufferOES_client_proc_t)ptr);
+	ptr = getProc("glBindRenderbufferOES", userData); set_glBindRenderbufferOES((glBindRenderbufferOES_client_proc_t)ptr);
+	ptr = getProc("glDeleteRenderbuffersOES", userData); set_glDeleteRenderbuffersOES((glDeleteRenderbuffersOES_client_proc_t)ptr);
+	ptr = getProc("glGenRenderbuffersOES", userData); set_glGenRenderbuffersOES((glGenRenderbuffersOES_client_proc_t)ptr);
+	ptr = getProc("glRenderbufferStorageOES", userData); set_glRenderbufferStorageOES((glRenderbufferStorageOES_client_proc_t)ptr);
+	ptr = getProc("glGetRenderbufferParameterivOES", userData); set_glGetRenderbufferParameterivOES((glGetRenderbufferParameterivOES_client_proc_t)ptr);
+	ptr = getProc("glIsFramebufferOES", userData); set_glIsFramebufferOES((glIsFramebufferOES_client_proc_t)ptr);
+	ptr = getProc("glBindFramebufferOES", userData); set_glBindFramebufferOES((glBindFramebufferOES_client_proc_t)ptr);
+	ptr = getProc("glDeleteFramebuffersOES", userData); set_glDeleteFramebuffersOES((glDeleteFramebuffersOES_client_proc_t)ptr);
+	ptr = getProc("glGenFramebuffersOES", userData); set_glGenFramebuffersOES((glGenFramebuffersOES_client_proc_t)ptr);
+	ptr = getProc("glCheckFramebufferStatusOES", userData); set_glCheckFramebufferStatusOES((glCheckFramebufferStatusOES_client_proc_t)ptr);
+	ptr = getProc("glFramebufferRenderbufferOES", userData); set_glFramebufferRenderbufferOES((glFramebufferRenderbufferOES_client_proc_t)ptr);
+	ptr = getProc("glFramebufferTexture2DOES", userData); set_glFramebufferTexture2DOES((glFramebufferTexture2DOES_client_proc_t)ptr);
+	ptr = getProc("glGetFramebufferAttachmentParameterivOES", userData); set_glGetFramebufferAttachmentParameterivOES((glGetFramebufferAttachmentParameterivOES_client_proc_t)ptr);
+	ptr = getProc("glGenerateMipmapOES", userData); set_glGenerateMipmapOES((glGenerateMipmapOES_client_proc_t)ptr);
+	ptr = getProc("glMapBufferOES", userData); set_glMapBufferOES((glMapBufferOES_client_proc_t)ptr);
+	ptr = getProc("glUnmapBufferOES", userData); set_glUnmapBufferOES((glUnmapBufferOES_client_proc_t)ptr);
+	ptr = getProc("glGetBufferPointervOES", userData); set_glGetBufferPointervOES((glGetBufferPointervOES_client_proc_t)ptr);
+	ptr = getProc("glCurrentPaletteMatrixOES", userData); set_glCurrentPaletteMatrixOES((glCurrentPaletteMatrixOES_client_proc_t)ptr);
+	ptr = getProc("glLoadPaletteFromModelViewMatrixOES", userData); set_glLoadPaletteFromModelViewMatrixOES((glLoadPaletteFromModelViewMatrixOES_client_proc_t)ptr);
+	ptr = getProc("glMatrixIndexPointerOES", userData); set_glMatrixIndexPointerOES((glMatrixIndexPointerOES_client_proc_t)ptr);
+	ptr = getProc("glWeightPointerOES", userData); set_glWeightPointerOES((glWeightPointerOES_client_proc_t)ptr);
+	ptr = getProc("glQueryMatrixxOES", userData); set_glQueryMatrixxOES((glQueryMatrixxOES_client_proc_t)ptr);
+	ptr = getProc("glDepthRangefOES", userData); set_glDepthRangefOES((glDepthRangefOES_client_proc_t)ptr);
+	ptr = getProc("glFrustumfOES", userData); set_glFrustumfOES((glFrustumfOES_client_proc_t)ptr);
+	ptr = getProc("glOrthofOES", userData); set_glOrthofOES((glOrthofOES_client_proc_t)ptr);
+	ptr = getProc("glClipPlanefOES", userData); set_glClipPlanefOES((glClipPlanefOES_client_proc_t)ptr);
+	ptr = getProc("glClipPlanefIMG", userData); set_glClipPlanefIMG((glClipPlanefIMG_client_proc_t)ptr);
+	ptr = getProc("glGetClipPlanefOES", userData); set_glGetClipPlanefOES((glGetClipPlanefOES_client_proc_t)ptr);
+	ptr = getProc("glClearDepthfOES", userData); set_glClearDepthfOES((glClearDepthfOES_client_proc_t)ptr);
+	ptr = getProc("glTexGenfOES", userData); set_glTexGenfOES((glTexGenfOES_client_proc_t)ptr);
+	ptr = getProc("glTexGenfvOES", userData); set_glTexGenfvOES((glTexGenfvOES_client_proc_t)ptr);
+	ptr = getProc("glTexGeniOES", userData); set_glTexGeniOES((glTexGeniOES_client_proc_t)ptr);
+	ptr = getProc("glTexGenivOES", userData); set_glTexGenivOES((glTexGenivOES_client_proc_t)ptr);
+	ptr = getProc("glTexGenxOES", userData); set_glTexGenxOES((glTexGenxOES_client_proc_t)ptr);
+	ptr = getProc("glTexGenxvOES", userData); set_glTexGenxvOES((glTexGenxvOES_client_proc_t)ptr);
+	ptr = getProc("glGetTexGenfvOES", userData); set_glGetTexGenfvOES((glGetTexGenfvOES_client_proc_t)ptr);
+	ptr = getProc("glGetTexGenivOES", userData); set_glGetTexGenivOES((glGetTexGenivOES_client_proc_t)ptr);
+	ptr = getProc("glGetTexGenxvOES", userData); set_glGetTexGenxvOES((glGetTexGenxvOES_client_proc_t)ptr);
+	ptr = getProc("glBindVertexArrayOES", userData); set_glBindVertexArrayOES((glBindVertexArrayOES_client_proc_t)ptr);
+	ptr = getProc("glDeleteVertexArraysOES", userData); set_glDeleteVertexArraysOES((glDeleteVertexArraysOES_client_proc_t)ptr);
+	ptr = getProc("glGenVertexArraysOES", userData); set_glGenVertexArraysOES((glGenVertexArraysOES_client_proc_t)ptr);
+	ptr = getProc("glIsVertexArrayOES", userData); set_glIsVertexArrayOES((glIsVertexArrayOES_client_proc_t)ptr);
+	ptr = getProc("glDiscardFramebufferEXT", userData); set_glDiscardFramebufferEXT((glDiscardFramebufferEXT_client_proc_t)ptr);
+	ptr = getProc("glMultiDrawArraysEXT", userData); set_glMultiDrawArraysEXT((glMultiDrawArraysEXT_client_proc_t)ptr);
+	ptr = getProc("glMultiDrawElementsEXT", userData); set_glMultiDrawElementsEXT((glMultiDrawElementsEXT_client_proc_t)ptr);
+	ptr = getProc("glMultiDrawArraysSUN", userData); set_glMultiDrawArraysSUN((glMultiDrawArraysSUN_client_proc_t)ptr);
+	ptr = getProc("glMultiDrawElementsSUN", userData); set_glMultiDrawElementsSUN((glMultiDrawElementsSUN_client_proc_t)ptr);
+	ptr = getProc("glRenderbufferStorageMultisampleIMG", userData); set_glRenderbufferStorageMultisampleIMG((glRenderbufferStorageMultisampleIMG_client_proc_t)ptr);
+	ptr = getProc("glFramebufferTexture2DMultisampleIMG", userData); set_glFramebufferTexture2DMultisampleIMG((glFramebufferTexture2DMultisampleIMG_client_proc_t)ptr);
+	ptr = getProc("glDeleteFencesNV", userData); set_glDeleteFencesNV((glDeleteFencesNV_client_proc_t)ptr);
+	ptr = getProc("glGenFencesNV", userData); set_glGenFencesNV((glGenFencesNV_client_proc_t)ptr);
+	ptr = getProc("glIsFenceNV", userData); set_glIsFenceNV((glIsFenceNV_client_proc_t)ptr);
+	ptr = getProc("glTestFenceNV", userData); set_glTestFenceNV((glTestFenceNV_client_proc_t)ptr);
+	ptr = getProc("glGetFenceivNV", userData); set_glGetFenceivNV((glGetFenceivNV_client_proc_t)ptr);
+	ptr = getProc("glFinishFenceNV", userData); set_glFinishFenceNV((glFinishFenceNV_client_proc_t)ptr);
+	ptr = getProc("glSetFenceNV", userData); set_glSetFenceNV((glSetFenceNV_client_proc_t)ptr);
+	ptr = getProc("glGetDriverControlsQCOM", userData); set_glGetDriverControlsQCOM((glGetDriverControlsQCOM_client_proc_t)ptr);
+	ptr = getProc("glGetDriverControlStringQCOM", userData); set_glGetDriverControlStringQCOM((glGetDriverControlStringQCOM_client_proc_t)ptr);
+	ptr = getProc("glEnableDriverControlQCOM", userData); set_glEnableDriverControlQCOM((glEnableDriverControlQCOM_client_proc_t)ptr);
+	ptr = getProc("glDisableDriverControlQCOM", userData); set_glDisableDriverControlQCOM((glDisableDriverControlQCOM_client_proc_t)ptr);
+	ptr = getProc("glExtGetTexturesQCOM", userData); set_glExtGetTexturesQCOM((glExtGetTexturesQCOM_client_proc_t)ptr);
+	ptr = getProc("glExtGetBuffersQCOM", userData); set_glExtGetBuffersQCOM((glExtGetBuffersQCOM_client_proc_t)ptr);
+	ptr = getProc("glExtGetRenderbuffersQCOM", userData); set_glExtGetRenderbuffersQCOM((glExtGetRenderbuffersQCOM_client_proc_t)ptr);
+	ptr = getProc("glExtGetFramebuffersQCOM", userData); set_glExtGetFramebuffersQCOM((glExtGetFramebuffersQCOM_client_proc_t)ptr);
+	ptr = getProc("glExtGetTexLevelParameterivQCOM", userData); set_glExtGetTexLevelParameterivQCOM((glExtGetTexLevelParameterivQCOM_client_proc_t)ptr);
+	ptr = getProc("glExtTexObjectStateOverrideiQCOM", userData); set_glExtTexObjectStateOverrideiQCOM((glExtTexObjectStateOverrideiQCOM_client_proc_t)ptr);
+	ptr = getProc("glExtGetTexSubImageQCOM", userData); set_glExtGetTexSubImageQCOM((glExtGetTexSubImageQCOM_client_proc_t)ptr);
+	ptr = getProc("glExtGetBufferPointervQCOM", userData); set_glExtGetBufferPointervQCOM((glExtGetBufferPointervQCOM_client_proc_t)ptr);
+	ptr = getProc("glExtGetShadersQCOM", userData); set_glExtGetShadersQCOM((glExtGetShadersQCOM_client_proc_t)ptr);
+	ptr = getProc("glExtGetProgramsQCOM", userData); set_glExtGetProgramsQCOM((glExtGetProgramsQCOM_client_proc_t)ptr);
+	ptr = getProc("glExtIsProgramBinaryQCOM", userData); set_glExtIsProgramBinaryQCOM((glExtIsProgramBinaryQCOM_client_proc_t)ptr);
+	ptr = getProc("glExtGetProgramBinarySourceQCOM", userData); set_glExtGetProgramBinarySourceQCOM((glExtGetProgramBinarySourceQCOM_client_proc_t)ptr);
+	ptr = getProc("glStartTilingQCOM", userData); set_glStartTilingQCOM((glStartTilingQCOM_client_proc_t)ptr);
+	ptr = getProc("glEndTilingQCOM", userData); set_glEndTilingQCOM((glEndTilingQCOM_client_proc_t)ptr);
+	return 0;
+}
+
diff --git a/opengl/system/GLESv1_enc/gl_client_context.h b/opengl/system/GLESv1_enc/gl_client_context.h
new file mode 100644
index 0000000..c0b83ad
--- /dev/null
+++ b/opengl/system/GLESv1_enc/gl_client_context.h
@@ -0,0 +1,603 @@
+// Generated Code - DO NOT EDIT !!
+// generated by 'emugen'
+#ifndef __gl_client_context_t_h
+#define __gl_client_context_t_h
+
+#include "gl_client_proc.h"
+
+
+struct gl_client_context_t {
+
+	glAlphaFunc_client_proc_t glAlphaFunc;
+	glClearColor_client_proc_t glClearColor;
+	glClearDepthf_client_proc_t glClearDepthf;
+	glClipPlanef_client_proc_t glClipPlanef;
+	glColor4f_client_proc_t glColor4f;
+	glDepthRangef_client_proc_t glDepthRangef;
+	glFogf_client_proc_t glFogf;
+	glFogfv_client_proc_t glFogfv;
+	glFrustumf_client_proc_t glFrustumf;
+	glGetClipPlanef_client_proc_t glGetClipPlanef;
+	glGetFloatv_client_proc_t glGetFloatv;
+	glGetLightfv_client_proc_t glGetLightfv;
+	glGetMaterialfv_client_proc_t glGetMaterialfv;
+	glGetTexEnvfv_client_proc_t glGetTexEnvfv;
+	glGetTexParameterfv_client_proc_t glGetTexParameterfv;
+	glLightModelf_client_proc_t glLightModelf;
+	glLightModelfv_client_proc_t glLightModelfv;
+	glLightf_client_proc_t glLightf;
+	glLightfv_client_proc_t glLightfv;
+	glLineWidth_client_proc_t glLineWidth;
+	glLoadMatrixf_client_proc_t glLoadMatrixf;
+	glMaterialf_client_proc_t glMaterialf;
+	glMaterialfv_client_proc_t glMaterialfv;
+	glMultMatrixf_client_proc_t glMultMatrixf;
+	glMultiTexCoord4f_client_proc_t glMultiTexCoord4f;
+	glNormal3f_client_proc_t glNormal3f;
+	glOrthof_client_proc_t glOrthof;
+	glPointParameterf_client_proc_t glPointParameterf;
+	glPointParameterfv_client_proc_t glPointParameterfv;
+	glPointSize_client_proc_t glPointSize;
+	glPolygonOffset_client_proc_t glPolygonOffset;
+	glRotatef_client_proc_t glRotatef;
+	glScalef_client_proc_t glScalef;
+	glTexEnvf_client_proc_t glTexEnvf;
+	glTexEnvfv_client_proc_t glTexEnvfv;
+	glTexParameterf_client_proc_t glTexParameterf;
+	glTexParameterfv_client_proc_t glTexParameterfv;
+	glTranslatef_client_proc_t glTranslatef;
+	glActiveTexture_client_proc_t glActiveTexture;
+	glAlphaFuncx_client_proc_t glAlphaFuncx;
+	glBindBuffer_client_proc_t glBindBuffer;
+	glBindTexture_client_proc_t glBindTexture;
+	glBlendFunc_client_proc_t glBlendFunc;
+	glBufferData_client_proc_t glBufferData;
+	glBufferSubData_client_proc_t glBufferSubData;
+	glClear_client_proc_t glClear;
+	glClearColorx_client_proc_t glClearColorx;
+	glClearDepthx_client_proc_t glClearDepthx;
+	glClearStencil_client_proc_t glClearStencil;
+	glClientActiveTexture_client_proc_t glClientActiveTexture;
+	glColor4ub_client_proc_t glColor4ub;
+	glColor4x_client_proc_t glColor4x;
+	glColorMask_client_proc_t glColorMask;
+	glColorPointer_client_proc_t glColorPointer;
+	glCompressedTexImage2D_client_proc_t glCompressedTexImage2D;
+	glCompressedTexSubImage2D_client_proc_t glCompressedTexSubImage2D;
+	glCopyTexImage2D_client_proc_t glCopyTexImage2D;
+	glCopyTexSubImage2D_client_proc_t glCopyTexSubImage2D;
+	glCullFace_client_proc_t glCullFace;
+	glDeleteBuffers_client_proc_t glDeleteBuffers;
+	glDeleteTextures_client_proc_t glDeleteTextures;
+	glDepthFunc_client_proc_t glDepthFunc;
+	glDepthMask_client_proc_t glDepthMask;
+	glDepthRangex_client_proc_t glDepthRangex;
+	glDisable_client_proc_t glDisable;
+	glDisableClientState_client_proc_t glDisableClientState;
+	glDrawArrays_client_proc_t glDrawArrays;
+	glDrawElements_client_proc_t glDrawElements;
+	glEnable_client_proc_t glEnable;
+	glEnableClientState_client_proc_t glEnableClientState;
+	glFinish_client_proc_t glFinish;
+	glFlush_client_proc_t glFlush;
+	glFogx_client_proc_t glFogx;
+	glFogxv_client_proc_t glFogxv;
+	glFrontFace_client_proc_t glFrontFace;
+	glFrustumx_client_proc_t glFrustumx;
+	glGetBooleanv_client_proc_t glGetBooleanv;
+	glGetBufferParameteriv_client_proc_t glGetBufferParameteriv;
+	glClipPlanex_client_proc_t glClipPlanex;
+	glGenBuffers_client_proc_t glGenBuffers;
+	glGenTextures_client_proc_t glGenTextures;
+	glGetError_client_proc_t glGetError;
+	glGetFixedv_client_proc_t glGetFixedv;
+	glGetIntegerv_client_proc_t glGetIntegerv;
+	glGetLightxv_client_proc_t glGetLightxv;
+	glGetMaterialxv_client_proc_t glGetMaterialxv;
+	glGetPointerv_client_proc_t glGetPointerv;
+	glGetString_client_proc_t glGetString;
+	glGetTexEnviv_client_proc_t glGetTexEnviv;
+	glGetTexEnvxv_client_proc_t glGetTexEnvxv;
+	glGetTexParameteriv_client_proc_t glGetTexParameteriv;
+	glGetTexParameterxv_client_proc_t glGetTexParameterxv;
+	glHint_client_proc_t glHint;
+	glIsBuffer_client_proc_t glIsBuffer;
+	glIsEnabled_client_proc_t glIsEnabled;
+	glIsTexture_client_proc_t glIsTexture;
+	glLightModelx_client_proc_t glLightModelx;
+	glLightModelxv_client_proc_t glLightModelxv;
+	glLightx_client_proc_t glLightx;
+	glLightxv_client_proc_t glLightxv;
+	glLineWidthx_client_proc_t glLineWidthx;
+	glLoadIdentity_client_proc_t glLoadIdentity;
+	glLoadMatrixx_client_proc_t glLoadMatrixx;
+	glLogicOp_client_proc_t glLogicOp;
+	glMaterialx_client_proc_t glMaterialx;
+	glMaterialxv_client_proc_t glMaterialxv;
+	glMatrixMode_client_proc_t glMatrixMode;
+	glMultMatrixx_client_proc_t glMultMatrixx;
+	glMultiTexCoord4x_client_proc_t glMultiTexCoord4x;
+	glNormal3x_client_proc_t glNormal3x;
+	glNormalPointer_client_proc_t glNormalPointer;
+	glOrthox_client_proc_t glOrthox;
+	glPixelStorei_client_proc_t glPixelStorei;
+	glPointParameterx_client_proc_t glPointParameterx;
+	glPointParameterxv_client_proc_t glPointParameterxv;
+	glPointSizex_client_proc_t glPointSizex;
+	glPolygonOffsetx_client_proc_t glPolygonOffsetx;
+	glPopMatrix_client_proc_t glPopMatrix;
+	glPushMatrix_client_proc_t glPushMatrix;
+	glReadPixels_client_proc_t glReadPixels;
+	glRotatex_client_proc_t glRotatex;
+	glSampleCoverage_client_proc_t glSampleCoverage;
+	glSampleCoveragex_client_proc_t glSampleCoveragex;
+	glScalex_client_proc_t glScalex;
+	glScissor_client_proc_t glScissor;
+	glShadeModel_client_proc_t glShadeModel;
+	glStencilFunc_client_proc_t glStencilFunc;
+	glStencilMask_client_proc_t glStencilMask;
+	glStencilOp_client_proc_t glStencilOp;
+	glTexCoordPointer_client_proc_t glTexCoordPointer;
+	glTexEnvi_client_proc_t glTexEnvi;
+	glTexEnvx_client_proc_t glTexEnvx;
+	glTexEnviv_client_proc_t glTexEnviv;
+	glTexEnvxv_client_proc_t glTexEnvxv;
+	glTexImage2D_client_proc_t glTexImage2D;
+	glTexParameteri_client_proc_t glTexParameteri;
+	glTexParameterx_client_proc_t glTexParameterx;
+	glTexParameteriv_client_proc_t glTexParameteriv;
+	glTexParameterxv_client_proc_t glTexParameterxv;
+	glTexSubImage2D_client_proc_t glTexSubImage2D;
+	glTranslatex_client_proc_t glTranslatex;
+	glVertexPointer_client_proc_t glVertexPointer;
+	glViewport_client_proc_t glViewport;
+	glPointSizePointerOES_client_proc_t glPointSizePointerOES;
+	glVertexPointerOffset_client_proc_t glVertexPointerOffset;
+	glColorPointerOffset_client_proc_t glColorPointerOffset;
+	glNormalPointerOffset_client_proc_t glNormalPointerOffset;
+	glPointSizePointerOffset_client_proc_t glPointSizePointerOffset;
+	glTexCoordPointerOffset_client_proc_t glTexCoordPointerOffset;
+	glWeightPointerOffset_client_proc_t glWeightPointerOffset;
+	glMatrixIndexPointerOffset_client_proc_t glMatrixIndexPointerOffset;
+	glVertexPointerData_client_proc_t glVertexPointerData;
+	glColorPointerData_client_proc_t glColorPointerData;
+	glNormalPointerData_client_proc_t glNormalPointerData;
+	glTexCoordPointerData_client_proc_t glTexCoordPointerData;
+	glPointSizePointerData_client_proc_t glPointSizePointerData;
+	glWeightPointerData_client_proc_t glWeightPointerData;
+	glMatrixIndexPointerData_client_proc_t glMatrixIndexPointerData;
+	glDrawElementsOffset_client_proc_t glDrawElementsOffset;
+	glDrawElementsData_client_proc_t glDrawElementsData;
+	glGetCompressedTextureFormats_client_proc_t glGetCompressedTextureFormats;
+	glFinishRoundTrip_client_proc_t glFinishRoundTrip;
+	glBlendEquationSeparateOES_client_proc_t glBlendEquationSeparateOES;
+	glBlendFuncSeparateOES_client_proc_t glBlendFuncSeparateOES;
+	glBlendEquationOES_client_proc_t glBlendEquationOES;
+	glDrawTexsOES_client_proc_t glDrawTexsOES;
+	glDrawTexiOES_client_proc_t glDrawTexiOES;
+	glDrawTexxOES_client_proc_t glDrawTexxOES;
+	glDrawTexsvOES_client_proc_t glDrawTexsvOES;
+	glDrawTexivOES_client_proc_t glDrawTexivOES;
+	glDrawTexxvOES_client_proc_t glDrawTexxvOES;
+	glDrawTexfOES_client_proc_t glDrawTexfOES;
+	glDrawTexfvOES_client_proc_t glDrawTexfvOES;
+	glEGLImageTargetTexture2DOES_client_proc_t glEGLImageTargetTexture2DOES;
+	glEGLImageTargetRenderbufferStorageOES_client_proc_t glEGLImageTargetRenderbufferStorageOES;
+	glAlphaFuncxOES_client_proc_t glAlphaFuncxOES;
+	glClearColorxOES_client_proc_t glClearColorxOES;
+	glClearDepthxOES_client_proc_t glClearDepthxOES;
+	glClipPlanexOES_client_proc_t glClipPlanexOES;
+	glClipPlanexIMG_client_proc_t glClipPlanexIMG;
+	glColor4xOES_client_proc_t glColor4xOES;
+	glDepthRangexOES_client_proc_t glDepthRangexOES;
+	glFogxOES_client_proc_t glFogxOES;
+	glFogxvOES_client_proc_t glFogxvOES;
+	glFrustumxOES_client_proc_t glFrustumxOES;
+	glGetClipPlanexOES_client_proc_t glGetClipPlanexOES;
+	glGetClipPlanex_client_proc_t glGetClipPlanex;
+	glGetFixedvOES_client_proc_t glGetFixedvOES;
+	glGetLightxvOES_client_proc_t glGetLightxvOES;
+	glGetMaterialxvOES_client_proc_t glGetMaterialxvOES;
+	glGetTexEnvxvOES_client_proc_t glGetTexEnvxvOES;
+	glGetTexParameterxvOES_client_proc_t glGetTexParameterxvOES;
+	glLightModelxOES_client_proc_t glLightModelxOES;
+	glLightModelxvOES_client_proc_t glLightModelxvOES;
+	glLightxOES_client_proc_t glLightxOES;
+	glLightxvOES_client_proc_t glLightxvOES;
+	glLineWidthxOES_client_proc_t glLineWidthxOES;
+	glLoadMatrixxOES_client_proc_t glLoadMatrixxOES;
+	glMaterialxOES_client_proc_t glMaterialxOES;
+	glMaterialxvOES_client_proc_t glMaterialxvOES;
+	glMultMatrixxOES_client_proc_t glMultMatrixxOES;
+	glMultiTexCoord4xOES_client_proc_t glMultiTexCoord4xOES;
+	glNormal3xOES_client_proc_t glNormal3xOES;
+	glOrthoxOES_client_proc_t glOrthoxOES;
+	glPointParameterxOES_client_proc_t glPointParameterxOES;
+	glPointParameterxvOES_client_proc_t glPointParameterxvOES;
+	glPointSizexOES_client_proc_t glPointSizexOES;
+	glPolygonOffsetxOES_client_proc_t glPolygonOffsetxOES;
+	glRotatexOES_client_proc_t glRotatexOES;
+	glSampleCoveragexOES_client_proc_t glSampleCoveragexOES;
+	glScalexOES_client_proc_t glScalexOES;
+	glTexEnvxOES_client_proc_t glTexEnvxOES;
+	glTexEnvxvOES_client_proc_t glTexEnvxvOES;
+	glTexParameterxOES_client_proc_t glTexParameterxOES;
+	glTexParameterxvOES_client_proc_t glTexParameterxvOES;
+	glTranslatexOES_client_proc_t glTranslatexOES;
+	glIsRenderbufferOES_client_proc_t glIsRenderbufferOES;
+	glBindRenderbufferOES_client_proc_t glBindRenderbufferOES;
+	glDeleteRenderbuffersOES_client_proc_t glDeleteRenderbuffersOES;
+	glGenRenderbuffersOES_client_proc_t glGenRenderbuffersOES;
+	glRenderbufferStorageOES_client_proc_t glRenderbufferStorageOES;
+	glGetRenderbufferParameterivOES_client_proc_t glGetRenderbufferParameterivOES;
+	glIsFramebufferOES_client_proc_t glIsFramebufferOES;
+	glBindFramebufferOES_client_proc_t glBindFramebufferOES;
+	glDeleteFramebuffersOES_client_proc_t glDeleteFramebuffersOES;
+	glGenFramebuffersOES_client_proc_t glGenFramebuffersOES;
+	glCheckFramebufferStatusOES_client_proc_t glCheckFramebufferStatusOES;
+	glFramebufferRenderbufferOES_client_proc_t glFramebufferRenderbufferOES;
+	glFramebufferTexture2DOES_client_proc_t glFramebufferTexture2DOES;
+	glGetFramebufferAttachmentParameterivOES_client_proc_t glGetFramebufferAttachmentParameterivOES;
+	glGenerateMipmapOES_client_proc_t glGenerateMipmapOES;
+	glMapBufferOES_client_proc_t glMapBufferOES;
+	glUnmapBufferOES_client_proc_t glUnmapBufferOES;
+	glGetBufferPointervOES_client_proc_t glGetBufferPointervOES;
+	glCurrentPaletteMatrixOES_client_proc_t glCurrentPaletteMatrixOES;
+	glLoadPaletteFromModelViewMatrixOES_client_proc_t glLoadPaletteFromModelViewMatrixOES;
+	glMatrixIndexPointerOES_client_proc_t glMatrixIndexPointerOES;
+	glWeightPointerOES_client_proc_t glWeightPointerOES;
+	glQueryMatrixxOES_client_proc_t glQueryMatrixxOES;
+	glDepthRangefOES_client_proc_t glDepthRangefOES;
+	glFrustumfOES_client_proc_t glFrustumfOES;
+	glOrthofOES_client_proc_t glOrthofOES;
+	glClipPlanefOES_client_proc_t glClipPlanefOES;
+	glClipPlanefIMG_client_proc_t glClipPlanefIMG;
+	glGetClipPlanefOES_client_proc_t glGetClipPlanefOES;
+	glClearDepthfOES_client_proc_t glClearDepthfOES;
+	glTexGenfOES_client_proc_t glTexGenfOES;
+	glTexGenfvOES_client_proc_t glTexGenfvOES;
+	glTexGeniOES_client_proc_t glTexGeniOES;
+	glTexGenivOES_client_proc_t glTexGenivOES;
+	glTexGenxOES_client_proc_t glTexGenxOES;
+	glTexGenxvOES_client_proc_t glTexGenxvOES;
+	glGetTexGenfvOES_client_proc_t glGetTexGenfvOES;
+	glGetTexGenivOES_client_proc_t glGetTexGenivOES;
+	glGetTexGenxvOES_client_proc_t glGetTexGenxvOES;
+	glBindVertexArrayOES_client_proc_t glBindVertexArrayOES;
+	glDeleteVertexArraysOES_client_proc_t glDeleteVertexArraysOES;
+	glGenVertexArraysOES_client_proc_t glGenVertexArraysOES;
+	glIsVertexArrayOES_client_proc_t glIsVertexArrayOES;
+	glDiscardFramebufferEXT_client_proc_t glDiscardFramebufferEXT;
+	glMultiDrawArraysEXT_client_proc_t glMultiDrawArraysEXT;
+	glMultiDrawElementsEXT_client_proc_t glMultiDrawElementsEXT;
+	glMultiDrawArraysSUN_client_proc_t glMultiDrawArraysSUN;
+	glMultiDrawElementsSUN_client_proc_t glMultiDrawElementsSUN;
+	glRenderbufferStorageMultisampleIMG_client_proc_t glRenderbufferStorageMultisampleIMG;
+	glFramebufferTexture2DMultisampleIMG_client_proc_t glFramebufferTexture2DMultisampleIMG;
+	glDeleteFencesNV_client_proc_t glDeleteFencesNV;
+	glGenFencesNV_client_proc_t glGenFencesNV;
+	glIsFenceNV_client_proc_t glIsFenceNV;
+	glTestFenceNV_client_proc_t glTestFenceNV;
+	glGetFenceivNV_client_proc_t glGetFenceivNV;
+	glFinishFenceNV_client_proc_t glFinishFenceNV;
+	glSetFenceNV_client_proc_t glSetFenceNV;
+	glGetDriverControlsQCOM_client_proc_t glGetDriverControlsQCOM;
+	glGetDriverControlStringQCOM_client_proc_t glGetDriverControlStringQCOM;
+	glEnableDriverControlQCOM_client_proc_t glEnableDriverControlQCOM;
+	glDisableDriverControlQCOM_client_proc_t glDisableDriverControlQCOM;
+	glExtGetTexturesQCOM_client_proc_t glExtGetTexturesQCOM;
+	glExtGetBuffersQCOM_client_proc_t glExtGetBuffersQCOM;
+	glExtGetRenderbuffersQCOM_client_proc_t glExtGetRenderbuffersQCOM;
+	glExtGetFramebuffersQCOM_client_proc_t glExtGetFramebuffersQCOM;
+	glExtGetTexLevelParameterivQCOM_client_proc_t glExtGetTexLevelParameterivQCOM;
+	glExtTexObjectStateOverrideiQCOM_client_proc_t glExtTexObjectStateOverrideiQCOM;
+	glExtGetTexSubImageQCOM_client_proc_t glExtGetTexSubImageQCOM;
+	glExtGetBufferPointervQCOM_client_proc_t glExtGetBufferPointervQCOM;
+	glExtGetShadersQCOM_client_proc_t glExtGetShadersQCOM;
+	glExtGetProgramsQCOM_client_proc_t glExtGetProgramsQCOM;
+	glExtIsProgramBinaryQCOM_client_proc_t glExtIsProgramBinaryQCOM;
+	glExtGetProgramBinarySourceQCOM_client_proc_t glExtGetProgramBinarySourceQCOM;
+	glStartTilingQCOM_client_proc_t glStartTilingQCOM;
+	glEndTilingQCOM_client_proc_t glEndTilingQCOM;
+	//Accessors 
+	virtual glAlphaFunc_client_proc_t set_glAlphaFunc(glAlphaFunc_client_proc_t f) { glAlphaFunc_client_proc_t retval = glAlphaFunc; glAlphaFunc = f; return retval;}
+	virtual glClearColor_client_proc_t set_glClearColor(glClearColor_client_proc_t f) { glClearColor_client_proc_t retval = glClearColor; glClearColor = f; return retval;}
+	virtual glClearDepthf_client_proc_t set_glClearDepthf(glClearDepthf_client_proc_t f) { glClearDepthf_client_proc_t retval = glClearDepthf; glClearDepthf = f; return retval;}
+	virtual glClipPlanef_client_proc_t set_glClipPlanef(glClipPlanef_client_proc_t f) { glClipPlanef_client_proc_t retval = glClipPlanef; glClipPlanef = f; return retval;}
+	virtual glColor4f_client_proc_t set_glColor4f(glColor4f_client_proc_t f) { glColor4f_client_proc_t retval = glColor4f; glColor4f = f; return retval;}
+	virtual glDepthRangef_client_proc_t set_glDepthRangef(glDepthRangef_client_proc_t f) { glDepthRangef_client_proc_t retval = glDepthRangef; glDepthRangef = f; return retval;}
+	virtual glFogf_client_proc_t set_glFogf(glFogf_client_proc_t f) { glFogf_client_proc_t retval = glFogf; glFogf = f; return retval;}
+	virtual glFogfv_client_proc_t set_glFogfv(glFogfv_client_proc_t f) { glFogfv_client_proc_t retval = glFogfv; glFogfv = f; return retval;}
+	virtual glFrustumf_client_proc_t set_glFrustumf(glFrustumf_client_proc_t f) { glFrustumf_client_proc_t retval = glFrustumf; glFrustumf = f; return retval;}
+	virtual glGetClipPlanef_client_proc_t set_glGetClipPlanef(glGetClipPlanef_client_proc_t f) { glGetClipPlanef_client_proc_t retval = glGetClipPlanef; glGetClipPlanef = f; return retval;}
+	virtual glGetFloatv_client_proc_t set_glGetFloatv(glGetFloatv_client_proc_t f) { glGetFloatv_client_proc_t retval = glGetFloatv; glGetFloatv = f; return retval;}
+	virtual glGetLightfv_client_proc_t set_glGetLightfv(glGetLightfv_client_proc_t f) { glGetLightfv_client_proc_t retval = glGetLightfv; glGetLightfv = f; return retval;}
+	virtual glGetMaterialfv_client_proc_t set_glGetMaterialfv(glGetMaterialfv_client_proc_t f) { glGetMaterialfv_client_proc_t retval = glGetMaterialfv; glGetMaterialfv = f; return retval;}
+	virtual glGetTexEnvfv_client_proc_t set_glGetTexEnvfv(glGetTexEnvfv_client_proc_t f) { glGetTexEnvfv_client_proc_t retval = glGetTexEnvfv; glGetTexEnvfv = f; return retval;}
+	virtual glGetTexParameterfv_client_proc_t set_glGetTexParameterfv(glGetTexParameterfv_client_proc_t f) { glGetTexParameterfv_client_proc_t retval = glGetTexParameterfv; glGetTexParameterfv = f; return retval;}
+	virtual glLightModelf_client_proc_t set_glLightModelf(glLightModelf_client_proc_t f) { glLightModelf_client_proc_t retval = glLightModelf; glLightModelf = f; return retval;}
+	virtual glLightModelfv_client_proc_t set_glLightModelfv(glLightModelfv_client_proc_t f) { glLightModelfv_client_proc_t retval = glLightModelfv; glLightModelfv = f; return retval;}
+	virtual glLightf_client_proc_t set_glLightf(glLightf_client_proc_t f) { glLightf_client_proc_t retval = glLightf; glLightf = f; return retval;}
+	virtual glLightfv_client_proc_t set_glLightfv(glLightfv_client_proc_t f) { glLightfv_client_proc_t retval = glLightfv; glLightfv = f; return retval;}
+	virtual glLineWidth_client_proc_t set_glLineWidth(glLineWidth_client_proc_t f) { glLineWidth_client_proc_t retval = glLineWidth; glLineWidth = f; return retval;}
+	virtual glLoadMatrixf_client_proc_t set_glLoadMatrixf(glLoadMatrixf_client_proc_t f) { glLoadMatrixf_client_proc_t retval = glLoadMatrixf; glLoadMatrixf = f; return retval;}
+	virtual glMaterialf_client_proc_t set_glMaterialf(glMaterialf_client_proc_t f) { glMaterialf_client_proc_t retval = glMaterialf; glMaterialf = f; return retval;}
+	virtual glMaterialfv_client_proc_t set_glMaterialfv(glMaterialfv_client_proc_t f) { glMaterialfv_client_proc_t retval = glMaterialfv; glMaterialfv = f; return retval;}
+	virtual glMultMatrixf_client_proc_t set_glMultMatrixf(glMultMatrixf_client_proc_t f) { glMultMatrixf_client_proc_t retval = glMultMatrixf; glMultMatrixf = f; return retval;}
+	virtual glMultiTexCoord4f_client_proc_t set_glMultiTexCoord4f(glMultiTexCoord4f_client_proc_t f) { glMultiTexCoord4f_client_proc_t retval = glMultiTexCoord4f; glMultiTexCoord4f = f; return retval;}
+	virtual glNormal3f_client_proc_t set_glNormal3f(glNormal3f_client_proc_t f) { glNormal3f_client_proc_t retval = glNormal3f; glNormal3f = f; return retval;}
+	virtual glOrthof_client_proc_t set_glOrthof(glOrthof_client_proc_t f) { glOrthof_client_proc_t retval = glOrthof; glOrthof = f; return retval;}
+	virtual glPointParameterf_client_proc_t set_glPointParameterf(glPointParameterf_client_proc_t f) { glPointParameterf_client_proc_t retval = glPointParameterf; glPointParameterf = f; return retval;}
+	virtual glPointParameterfv_client_proc_t set_glPointParameterfv(glPointParameterfv_client_proc_t f) { glPointParameterfv_client_proc_t retval = glPointParameterfv; glPointParameterfv = f; return retval;}
+	virtual glPointSize_client_proc_t set_glPointSize(glPointSize_client_proc_t f) { glPointSize_client_proc_t retval = glPointSize; glPointSize = f; return retval;}
+	virtual glPolygonOffset_client_proc_t set_glPolygonOffset(glPolygonOffset_client_proc_t f) { glPolygonOffset_client_proc_t retval = glPolygonOffset; glPolygonOffset = f; return retval;}
+	virtual glRotatef_client_proc_t set_glRotatef(glRotatef_client_proc_t f) { glRotatef_client_proc_t retval = glRotatef; glRotatef = f; return retval;}
+	virtual glScalef_client_proc_t set_glScalef(glScalef_client_proc_t f) { glScalef_client_proc_t retval = glScalef; glScalef = f; return retval;}
+	virtual glTexEnvf_client_proc_t set_glTexEnvf(glTexEnvf_client_proc_t f) { glTexEnvf_client_proc_t retval = glTexEnvf; glTexEnvf = f; return retval;}
+	virtual glTexEnvfv_client_proc_t set_glTexEnvfv(glTexEnvfv_client_proc_t f) { glTexEnvfv_client_proc_t retval = glTexEnvfv; glTexEnvfv = f; return retval;}
+	virtual glTexParameterf_client_proc_t set_glTexParameterf(glTexParameterf_client_proc_t f) { glTexParameterf_client_proc_t retval = glTexParameterf; glTexParameterf = f; return retval;}
+	virtual glTexParameterfv_client_proc_t set_glTexParameterfv(glTexParameterfv_client_proc_t f) { glTexParameterfv_client_proc_t retval = glTexParameterfv; glTexParameterfv = f; return retval;}
+	virtual glTranslatef_client_proc_t set_glTranslatef(glTranslatef_client_proc_t f) { glTranslatef_client_proc_t retval = glTranslatef; glTranslatef = f; return retval;}
+	virtual glActiveTexture_client_proc_t set_glActiveTexture(glActiveTexture_client_proc_t f) { glActiveTexture_client_proc_t retval = glActiveTexture; glActiveTexture = f; return retval;}
+	virtual glAlphaFuncx_client_proc_t set_glAlphaFuncx(glAlphaFuncx_client_proc_t f) { glAlphaFuncx_client_proc_t retval = glAlphaFuncx; glAlphaFuncx = f; return retval;}
+	virtual glBindBuffer_client_proc_t set_glBindBuffer(glBindBuffer_client_proc_t f) { glBindBuffer_client_proc_t retval = glBindBuffer; glBindBuffer = f; return retval;}
+	virtual glBindTexture_client_proc_t set_glBindTexture(glBindTexture_client_proc_t f) { glBindTexture_client_proc_t retval = glBindTexture; glBindTexture = f; return retval;}
+	virtual glBlendFunc_client_proc_t set_glBlendFunc(glBlendFunc_client_proc_t f) { glBlendFunc_client_proc_t retval = glBlendFunc; glBlendFunc = f; return retval;}
+	virtual glBufferData_client_proc_t set_glBufferData(glBufferData_client_proc_t f) { glBufferData_client_proc_t retval = glBufferData; glBufferData = f; return retval;}
+	virtual glBufferSubData_client_proc_t set_glBufferSubData(glBufferSubData_client_proc_t f) { glBufferSubData_client_proc_t retval = glBufferSubData; glBufferSubData = f; return retval;}
+	virtual glClear_client_proc_t set_glClear(glClear_client_proc_t f) { glClear_client_proc_t retval = glClear; glClear = f; return retval;}
+	virtual glClearColorx_client_proc_t set_glClearColorx(glClearColorx_client_proc_t f) { glClearColorx_client_proc_t retval = glClearColorx; glClearColorx = f; return retval;}
+	virtual glClearDepthx_client_proc_t set_glClearDepthx(glClearDepthx_client_proc_t f) { glClearDepthx_client_proc_t retval = glClearDepthx; glClearDepthx = f; return retval;}
+	virtual glClearStencil_client_proc_t set_glClearStencil(glClearStencil_client_proc_t f) { glClearStencil_client_proc_t retval = glClearStencil; glClearStencil = f; return retval;}
+	virtual glClientActiveTexture_client_proc_t set_glClientActiveTexture(glClientActiveTexture_client_proc_t f) { glClientActiveTexture_client_proc_t retval = glClientActiveTexture; glClientActiveTexture = f; return retval;}
+	virtual glColor4ub_client_proc_t set_glColor4ub(glColor4ub_client_proc_t f) { glColor4ub_client_proc_t retval = glColor4ub; glColor4ub = f; return retval;}
+	virtual glColor4x_client_proc_t set_glColor4x(glColor4x_client_proc_t f) { glColor4x_client_proc_t retval = glColor4x; glColor4x = f; return retval;}
+	virtual glColorMask_client_proc_t set_glColorMask(glColorMask_client_proc_t f) { glColorMask_client_proc_t retval = glColorMask; glColorMask = f; return retval;}
+	virtual glColorPointer_client_proc_t set_glColorPointer(glColorPointer_client_proc_t f) { glColorPointer_client_proc_t retval = glColorPointer; glColorPointer = f; return retval;}
+	virtual glCompressedTexImage2D_client_proc_t set_glCompressedTexImage2D(glCompressedTexImage2D_client_proc_t f) { glCompressedTexImage2D_client_proc_t retval = glCompressedTexImage2D; glCompressedTexImage2D = f; return retval;}
+	virtual glCompressedTexSubImage2D_client_proc_t set_glCompressedTexSubImage2D(glCompressedTexSubImage2D_client_proc_t f) { glCompressedTexSubImage2D_client_proc_t retval = glCompressedTexSubImage2D; glCompressedTexSubImage2D = f; return retval;}
+	virtual glCopyTexImage2D_client_proc_t set_glCopyTexImage2D(glCopyTexImage2D_client_proc_t f) { glCopyTexImage2D_client_proc_t retval = glCopyTexImage2D; glCopyTexImage2D = f; return retval;}
+	virtual glCopyTexSubImage2D_client_proc_t set_glCopyTexSubImage2D(glCopyTexSubImage2D_client_proc_t f) { glCopyTexSubImage2D_client_proc_t retval = glCopyTexSubImage2D; glCopyTexSubImage2D = f; return retval;}
+	virtual glCullFace_client_proc_t set_glCullFace(glCullFace_client_proc_t f) { glCullFace_client_proc_t retval = glCullFace; glCullFace = f; return retval;}
+	virtual glDeleteBuffers_client_proc_t set_glDeleteBuffers(glDeleteBuffers_client_proc_t f) { glDeleteBuffers_client_proc_t retval = glDeleteBuffers; glDeleteBuffers = f; return retval;}
+	virtual glDeleteTextures_client_proc_t set_glDeleteTextures(glDeleteTextures_client_proc_t f) { glDeleteTextures_client_proc_t retval = glDeleteTextures; glDeleteTextures = f; return retval;}
+	virtual glDepthFunc_client_proc_t set_glDepthFunc(glDepthFunc_client_proc_t f) { glDepthFunc_client_proc_t retval = glDepthFunc; glDepthFunc = f; return retval;}
+	virtual glDepthMask_client_proc_t set_glDepthMask(glDepthMask_client_proc_t f) { glDepthMask_client_proc_t retval = glDepthMask; glDepthMask = f; return retval;}
+	virtual glDepthRangex_client_proc_t set_glDepthRangex(glDepthRangex_client_proc_t f) { glDepthRangex_client_proc_t retval = glDepthRangex; glDepthRangex = f; return retval;}
+	virtual glDisable_client_proc_t set_glDisable(glDisable_client_proc_t f) { glDisable_client_proc_t retval = glDisable; glDisable = f; return retval;}
+	virtual glDisableClientState_client_proc_t set_glDisableClientState(glDisableClientState_client_proc_t f) { glDisableClientState_client_proc_t retval = glDisableClientState; glDisableClientState = f; return retval;}
+	virtual glDrawArrays_client_proc_t set_glDrawArrays(glDrawArrays_client_proc_t f) { glDrawArrays_client_proc_t retval = glDrawArrays; glDrawArrays = f; return retval;}
+	virtual glDrawElements_client_proc_t set_glDrawElements(glDrawElements_client_proc_t f) { glDrawElements_client_proc_t retval = glDrawElements; glDrawElements = f; return retval;}
+	virtual glEnable_client_proc_t set_glEnable(glEnable_client_proc_t f) { glEnable_client_proc_t retval = glEnable; glEnable = f; return retval;}
+	virtual glEnableClientState_client_proc_t set_glEnableClientState(glEnableClientState_client_proc_t f) { glEnableClientState_client_proc_t retval = glEnableClientState; glEnableClientState = f; return retval;}
+	virtual glFinish_client_proc_t set_glFinish(glFinish_client_proc_t f) { glFinish_client_proc_t retval = glFinish; glFinish = f; return retval;}
+	virtual glFlush_client_proc_t set_glFlush(glFlush_client_proc_t f) { glFlush_client_proc_t retval = glFlush; glFlush = f; return retval;}
+	virtual glFogx_client_proc_t set_glFogx(glFogx_client_proc_t f) { glFogx_client_proc_t retval = glFogx; glFogx = f; return retval;}
+	virtual glFogxv_client_proc_t set_glFogxv(glFogxv_client_proc_t f) { glFogxv_client_proc_t retval = glFogxv; glFogxv = f; return retval;}
+	virtual glFrontFace_client_proc_t set_glFrontFace(glFrontFace_client_proc_t f) { glFrontFace_client_proc_t retval = glFrontFace; glFrontFace = f; return retval;}
+	virtual glFrustumx_client_proc_t set_glFrustumx(glFrustumx_client_proc_t f) { glFrustumx_client_proc_t retval = glFrustumx; glFrustumx = f; return retval;}
+	virtual glGetBooleanv_client_proc_t set_glGetBooleanv(glGetBooleanv_client_proc_t f) { glGetBooleanv_client_proc_t retval = glGetBooleanv; glGetBooleanv = f; return retval;}
+	virtual glGetBufferParameteriv_client_proc_t set_glGetBufferParameteriv(glGetBufferParameteriv_client_proc_t f) { glGetBufferParameteriv_client_proc_t retval = glGetBufferParameteriv; glGetBufferParameteriv = f; return retval;}
+	virtual glClipPlanex_client_proc_t set_glClipPlanex(glClipPlanex_client_proc_t f) { glClipPlanex_client_proc_t retval = glClipPlanex; glClipPlanex = f; return retval;}
+	virtual glGenBuffers_client_proc_t set_glGenBuffers(glGenBuffers_client_proc_t f) { glGenBuffers_client_proc_t retval = glGenBuffers; glGenBuffers = f; return retval;}
+	virtual glGenTextures_client_proc_t set_glGenTextures(glGenTextures_client_proc_t f) { glGenTextures_client_proc_t retval = glGenTextures; glGenTextures = f; return retval;}
+	virtual glGetError_client_proc_t set_glGetError(glGetError_client_proc_t f) { glGetError_client_proc_t retval = glGetError; glGetError = f; return retval;}
+	virtual glGetFixedv_client_proc_t set_glGetFixedv(glGetFixedv_client_proc_t f) { glGetFixedv_client_proc_t retval = glGetFixedv; glGetFixedv = f; return retval;}
+	virtual glGetIntegerv_client_proc_t set_glGetIntegerv(glGetIntegerv_client_proc_t f) { glGetIntegerv_client_proc_t retval = glGetIntegerv; glGetIntegerv = f; return retval;}
+	virtual glGetLightxv_client_proc_t set_glGetLightxv(glGetLightxv_client_proc_t f) { glGetLightxv_client_proc_t retval = glGetLightxv; glGetLightxv = f; return retval;}
+	virtual glGetMaterialxv_client_proc_t set_glGetMaterialxv(glGetMaterialxv_client_proc_t f) { glGetMaterialxv_client_proc_t retval = glGetMaterialxv; glGetMaterialxv = f; return retval;}
+	virtual glGetPointerv_client_proc_t set_glGetPointerv(glGetPointerv_client_proc_t f) { glGetPointerv_client_proc_t retval = glGetPointerv; glGetPointerv = f; return retval;}
+	virtual glGetString_client_proc_t set_glGetString(glGetString_client_proc_t f) { glGetString_client_proc_t retval = glGetString; glGetString = f; return retval;}
+	virtual glGetTexEnviv_client_proc_t set_glGetTexEnviv(glGetTexEnviv_client_proc_t f) { glGetTexEnviv_client_proc_t retval = glGetTexEnviv; glGetTexEnviv = f; return retval;}
+	virtual glGetTexEnvxv_client_proc_t set_glGetTexEnvxv(glGetTexEnvxv_client_proc_t f) { glGetTexEnvxv_client_proc_t retval = glGetTexEnvxv; glGetTexEnvxv = f; return retval;}
+	virtual glGetTexParameteriv_client_proc_t set_glGetTexParameteriv(glGetTexParameteriv_client_proc_t f) { glGetTexParameteriv_client_proc_t retval = glGetTexParameteriv; glGetTexParameteriv = f; return retval;}
+	virtual glGetTexParameterxv_client_proc_t set_glGetTexParameterxv(glGetTexParameterxv_client_proc_t f) { glGetTexParameterxv_client_proc_t retval = glGetTexParameterxv; glGetTexParameterxv = f; return retval;}
+	virtual glHint_client_proc_t set_glHint(glHint_client_proc_t f) { glHint_client_proc_t retval = glHint; glHint = f; return retval;}
+	virtual glIsBuffer_client_proc_t set_glIsBuffer(glIsBuffer_client_proc_t f) { glIsBuffer_client_proc_t retval = glIsBuffer; glIsBuffer = f; return retval;}
+	virtual glIsEnabled_client_proc_t set_glIsEnabled(glIsEnabled_client_proc_t f) { glIsEnabled_client_proc_t retval = glIsEnabled; glIsEnabled = f; return retval;}
+	virtual glIsTexture_client_proc_t set_glIsTexture(glIsTexture_client_proc_t f) { glIsTexture_client_proc_t retval = glIsTexture; glIsTexture = f; return retval;}
+	virtual glLightModelx_client_proc_t set_glLightModelx(glLightModelx_client_proc_t f) { glLightModelx_client_proc_t retval = glLightModelx; glLightModelx = f; return retval;}
+	virtual glLightModelxv_client_proc_t set_glLightModelxv(glLightModelxv_client_proc_t f) { glLightModelxv_client_proc_t retval = glLightModelxv; glLightModelxv = f; return retval;}
+	virtual glLightx_client_proc_t set_glLightx(glLightx_client_proc_t f) { glLightx_client_proc_t retval = glLightx; glLightx = f; return retval;}
+	virtual glLightxv_client_proc_t set_glLightxv(glLightxv_client_proc_t f) { glLightxv_client_proc_t retval = glLightxv; glLightxv = f; return retval;}
+	virtual glLineWidthx_client_proc_t set_glLineWidthx(glLineWidthx_client_proc_t f) { glLineWidthx_client_proc_t retval = glLineWidthx; glLineWidthx = f; return retval;}
+	virtual glLoadIdentity_client_proc_t set_glLoadIdentity(glLoadIdentity_client_proc_t f) { glLoadIdentity_client_proc_t retval = glLoadIdentity; glLoadIdentity = f; return retval;}
+	virtual glLoadMatrixx_client_proc_t set_glLoadMatrixx(glLoadMatrixx_client_proc_t f) { glLoadMatrixx_client_proc_t retval = glLoadMatrixx; glLoadMatrixx = f; return retval;}
+	virtual glLogicOp_client_proc_t set_glLogicOp(glLogicOp_client_proc_t f) { glLogicOp_client_proc_t retval = glLogicOp; glLogicOp = f; return retval;}
+	virtual glMaterialx_client_proc_t set_glMaterialx(glMaterialx_client_proc_t f) { glMaterialx_client_proc_t retval = glMaterialx; glMaterialx = f; return retval;}
+	virtual glMaterialxv_client_proc_t set_glMaterialxv(glMaterialxv_client_proc_t f) { glMaterialxv_client_proc_t retval = glMaterialxv; glMaterialxv = f; return retval;}
+	virtual glMatrixMode_client_proc_t set_glMatrixMode(glMatrixMode_client_proc_t f) { glMatrixMode_client_proc_t retval = glMatrixMode; glMatrixMode = f; return retval;}
+	virtual glMultMatrixx_client_proc_t set_glMultMatrixx(glMultMatrixx_client_proc_t f) { glMultMatrixx_client_proc_t retval = glMultMatrixx; glMultMatrixx = f; return retval;}
+	virtual glMultiTexCoord4x_client_proc_t set_glMultiTexCoord4x(glMultiTexCoord4x_client_proc_t f) { glMultiTexCoord4x_client_proc_t retval = glMultiTexCoord4x; glMultiTexCoord4x = f; return retval;}
+	virtual glNormal3x_client_proc_t set_glNormal3x(glNormal3x_client_proc_t f) { glNormal3x_client_proc_t retval = glNormal3x; glNormal3x = f; return retval;}
+	virtual glNormalPointer_client_proc_t set_glNormalPointer(glNormalPointer_client_proc_t f) { glNormalPointer_client_proc_t retval = glNormalPointer; glNormalPointer = f; return retval;}
+	virtual glOrthox_client_proc_t set_glOrthox(glOrthox_client_proc_t f) { glOrthox_client_proc_t retval = glOrthox; glOrthox = f; return retval;}
+	virtual glPixelStorei_client_proc_t set_glPixelStorei(glPixelStorei_client_proc_t f) { glPixelStorei_client_proc_t retval = glPixelStorei; glPixelStorei = f; return retval;}
+	virtual glPointParameterx_client_proc_t set_glPointParameterx(glPointParameterx_client_proc_t f) { glPointParameterx_client_proc_t retval = glPointParameterx; glPointParameterx = f; return retval;}
+	virtual glPointParameterxv_client_proc_t set_glPointParameterxv(glPointParameterxv_client_proc_t f) { glPointParameterxv_client_proc_t retval = glPointParameterxv; glPointParameterxv = f; return retval;}
+	virtual glPointSizex_client_proc_t set_glPointSizex(glPointSizex_client_proc_t f) { glPointSizex_client_proc_t retval = glPointSizex; glPointSizex = f; return retval;}
+	virtual glPolygonOffsetx_client_proc_t set_glPolygonOffsetx(glPolygonOffsetx_client_proc_t f) { glPolygonOffsetx_client_proc_t retval = glPolygonOffsetx; glPolygonOffsetx = f; return retval;}
+	virtual glPopMatrix_client_proc_t set_glPopMatrix(glPopMatrix_client_proc_t f) { glPopMatrix_client_proc_t retval = glPopMatrix; glPopMatrix = f; return retval;}
+	virtual glPushMatrix_client_proc_t set_glPushMatrix(glPushMatrix_client_proc_t f) { glPushMatrix_client_proc_t retval = glPushMatrix; glPushMatrix = f; return retval;}
+	virtual glReadPixels_client_proc_t set_glReadPixels(glReadPixels_client_proc_t f) { glReadPixels_client_proc_t retval = glReadPixels; glReadPixels = f; return retval;}
+	virtual glRotatex_client_proc_t set_glRotatex(glRotatex_client_proc_t f) { glRotatex_client_proc_t retval = glRotatex; glRotatex = f; return retval;}
+	virtual glSampleCoverage_client_proc_t set_glSampleCoverage(glSampleCoverage_client_proc_t f) { glSampleCoverage_client_proc_t retval = glSampleCoverage; glSampleCoverage = f; return retval;}
+	virtual glSampleCoveragex_client_proc_t set_glSampleCoveragex(glSampleCoveragex_client_proc_t f) { glSampleCoveragex_client_proc_t retval = glSampleCoveragex; glSampleCoveragex = f; return retval;}
+	virtual glScalex_client_proc_t set_glScalex(glScalex_client_proc_t f) { glScalex_client_proc_t retval = glScalex; glScalex = f; return retval;}
+	virtual glScissor_client_proc_t set_glScissor(glScissor_client_proc_t f) { glScissor_client_proc_t retval = glScissor; glScissor = f; return retval;}
+	virtual glShadeModel_client_proc_t set_glShadeModel(glShadeModel_client_proc_t f) { glShadeModel_client_proc_t retval = glShadeModel; glShadeModel = f; return retval;}
+	virtual glStencilFunc_client_proc_t set_glStencilFunc(glStencilFunc_client_proc_t f) { glStencilFunc_client_proc_t retval = glStencilFunc; glStencilFunc = f; return retval;}
+	virtual glStencilMask_client_proc_t set_glStencilMask(glStencilMask_client_proc_t f) { glStencilMask_client_proc_t retval = glStencilMask; glStencilMask = f; return retval;}
+	virtual glStencilOp_client_proc_t set_glStencilOp(glStencilOp_client_proc_t f) { glStencilOp_client_proc_t retval = glStencilOp; glStencilOp = f; return retval;}
+	virtual glTexCoordPointer_client_proc_t set_glTexCoordPointer(glTexCoordPointer_client_proc_t f) { glTexCoordPointer_client_proc_t retval = glTexCoordPointer; glTexCoordPointer = f; return retval;}
+	virtual glTexEnvi_client_proc_t set_glTexEnvi(glTexEnvi_client_proc_t f) { glTexEnvi_client_proc_t retval = glTexEnvi; glTexEnvi = f; return retval;}
+	virtual glTexEnvx_client_proc_t set_glTexEnvx(glTexEnvx_client_proc_t f) { glTexEnvx_client_proc_t retval = glTexEnvx; glTexEnvx = f; return retval;}
+	virtual glTexEnviv_client_proc_t set_glTexEnviv(glTexEnviv_client_proc_t f) { glTexEnviv_client_proc_t retval = glTexEnviv; glTexEnviv = f; return retval;}
+	virtual glTexEnvxv_client_proc_t set_glTexEnvxv(glTexEnvxv_client_proc_t f) { glTexEnvxv_client_proc_t retval = glTexEnvxv; glTexEnvxv = f; return retval;}
+	virtual glTexImage2D_client_proc_t set_glTexImage2D(glTexImage2D_client_proc_t f) { glTexImage2D_client_proc_t retval = glTexImage2D; glTexImage2D = f; return retval;}
+	virtual glTexParameteri_client_proc_t set_glTexParameteri(glTexParameteri_client_proc_t f) { glTexParameteri_client_proc_t retval = glTexParameteri; glTexParameteri = f; return retval;}
+	virtual glTexParameterx_client_proc_t set_glTexParameterx(glTexParameterx_client_proc_t f) { glTexParameterx_client_proc_t retval = glTexParameterx; glTexParameterx = f; return retval;}
+	virtual glTexParameteriv_client_proc_t set_glTexParameteriv(glTexParameteriv_client_proc_t f) { glTexParameteriv_client_proc_t retval = glTexParameteriv; glTexParameteriv = f; return retval;}
+	virtual glTexParameterxv_client_proc_t set_glTexParameterxv(glTexParameterxv_client_proc_t f) { glTexParameterxv_client_proc_t retval = glTexParameterxv; glTexParameterxv = f; return retval;}
+	virtual glTexSubImage2D_client_proc_t set_glTexSubImage2D(glTexSubImage2D_client_proc_t f) { glTexSubImage2D_client_proc_t retval = glTexSubImage2D; glTexSubImage2D = f; return retval;}
+	virtual glTranslatex_client_proc_t set_glTranslatex(glTranslatex_client_proc_t f) { glTranslatex_client_proc_t retval = glTranslatex; glTranslatex = f; return retval;}
+	virtual glVertexPointer_client_proc_t set_glVertexPointer(glVertexPointer_client_proc_t f) { glVertexPointer_client_proc_t retval = glVertexPointer; glVertexPointer = f; return retval;}
+	virtual glViewport_client_proc_t set_glViewport(glViewport_client_proc_t f) { glViewport_client_proc_t retval = glViewport; glViewport = f; return retval;}
+	virtual glPointSizePointerOES_client_proc_t set_glPointSizePointerOES(glPointSizePointerOES_client_proc_t f) { glPointSizePointerOES_client_proc_t retval = glPointSizePointerOES; glPointSizePointerOES = f; return retval;}
+	virtual glVertexPointerOffset_client_proc_t set_glVertexPointerOffset(glVertexPointerOffset_client_proc_t f) { glVertexPointerOffset_client_proc_t retval = glVertexPointerOffset; glVertexPointerOffset = f; return retval;}
+	virtual glColorPointerOffset_client_proc_t set_glColorPointerOffset(glColorPointerOffset_client_proc_t f) { glColorPointerOffset_client_proc_t retval = glColorPointerOffset; glColorPointerOffset = f; return retval;}
+	virtual glNormalPointerOffset_client_proc_t set_glNormalPointerOffset(glNormalPointerOffset_client_proc_t f) { glNormalPointerOffset_client_proc_t retval = glNormalPointerOffset; glNormalPointerOffset = f; return retval;}
+	virtual glPointSizePointerOffset_client_proc_t set_glPointSizePointerOffset(glPointSizePointerOffset_client_proc_t f) { glPointSizePointerOffset_client_proc_t retval = glPointSizePointerOffset; glPointSizePointerOffset = f; return retval;}
+	virtual glTexCoordPointerOffset_client_proc_t set_glTexCoordPointerOffset(glTexCoordPointerOffset_client_proc_t f) { glTexCoordPointerOffset_client_proc_t retval = glTexCoordPointerOffset; glTexCoordPointerOffset = f; return retval;}
+	virtual glWeightPointerOffset_client_proc_t set_glWeightPointerOffset(glWeightPointerOffset_client_proc_t f) { glWeightPointerOffset_client_proc_t retval = glWeightPointerOffset; glWeightPointerOffset = f; return retval;}
+	virtual glMatrixIndexPointerOffset_client_proc_t set_glMatrixIndexPointerOffset(glMatrixIndexPointerOffset_client_proc_t f) { glMatrixIndexPointerOffset_client_proc_t retval = glMatrixIndexPointerOffset; glMatrixIndexPointerOffset = f; return retval;}
+	virtual glVertexPointerData_client_proc_t set_glVertexPointerData(glVertexPointerData_client_proc_t f) { glVertexPointerData_client_proc_t retval = glVertexPointerData; glVertexPointerData = f; return retval;}
+	virtual glColorPointerData_client_proc_t set_glColorPointerData(glColorPointerData_client_proc_t f) { glColorPointerData_client_proc_t retval = glColorPointerData; glColorPointerData = f; return retval;}
+	virtual glNormalPointerData_client_proc_t set_glNormalPointerData(glNormalPointerData_client_proc_t f) { glNormalPointerData_client_proc_t retval = glNormalPointerData; glNormalPointerData = f; return retval;}
+	virtual glTexCoordPointerData_client_proc_t set_glTexCoordPointerData(glTexCoordPointerData_client_proc_t f) { glTexCoordPointerData_client_proc_t retval = glTexCoordPointerData; glTexCoordPointerData = f; return retval;}
+	virtual glPointSizePointerData_client_proc_t set_glPointSizePointerData(glPointSizePointerData_client_proc_t f) { glPointSizePointerData_client_proc_t retval = glPointSizePointerData; glPointSizePointerData = f; return retval;}
+	virtual glWeightPointerData_client_proc_t set_glWeightPointerData(glWeightPointerData_client_proc_t f) { glWeightPointerData_client_proc_t retval = glWeightPointerData; glWeightPointerData = f; return retval;}
+	virtual glMatrixIndexPointerData_client_proc_t set_glMatrixIndexPointerData(glMatrixIndexPointerData_client_proc_t f) { glMatrixIndexPointerData_client_proc_t retval = glMatrixIndexPointerData; glMatrixIndexPointerData = f; return retval;}
+	virtual glDrawElementsOffset_client_proc_t set_glDrawElementsOffset(glDrawElementsOffset_client_proc_t f) { glDrawElementsOffset_client_proc_t retval = glDrawElementsOffset; glDrawElementsOffset = f; return retval;}
+	virtual glDrawElementsData_client_proc_t set_glDrawElementsData(glDrawElementsData_client_proc_t f) { glDrawElementsData_client_proc_t retval = glDrawElementsData; glDrawElementsData = f; return retval;}
+	virtual glGetCompressedTextureFormats_client_proc_t set_glGetCompressedTextureFormats(glGetCompressedTextureFormats_client_proc_t f) { glGetCompressedTextureFormats_client_proc_t retval = glGetCompressedTextureFormats; glGetCompressedTextureFormats = f; return retval;}
+	virtual glFinishRoundTrip_client_proc_t set_glFinishRoundTrip(glFinishRoundTrip_client_proc_t f) { glFinishRoundTrip_client_proc_t retval = glFinishRoundTrip; glFinishRoundTrip = f; return retval;}
+	virtual glBlendEquationSeparateOES_client_proc_t set_glBlendEquationSeparateOES(glBlendEquationSeparateOES_client_proc_t f) { glBlendEquationSeparateOES_client_proc_t retval = glBlendEquationSeparateOES; glBlendEquationSeparateOES = f; return retval;}
+	virtual glBlendFuncSeparateOES_client_proc_t set_glBlendFuncSeparateOES(glBlendFuncSeparateOES_client_proc_t f) { glBlendFuncSeparateOES_client_proc_t retval = glBlendFuncSeparateOES; glBlendFuncSeparateOES = f; return retval;}
+	virtual glBlendEquationOES_client_proc_t set_glBlendEquationOES(glBlendEquationOES_client_proc_t f) { glBlendEquationOES_client_proc_t retval = glBlendEquationOES; glBlendEquationOES = f; return retval;}
+	virtual glDrawTexsOES_client_proc_t set_glDrawTexsOES(glDrawTexsOES_client_proc_t f) { glDrawTexsOES_client_proc_t retval = glDrawTexsOES; glDrawTexsOES = f; return retval;}
+	virtual glDrawTexiOES_client_proc_t set_glDrawTexiOES(glDrawTexiOES_client_proc_t f) { glDrawTexiOES_client_proc_t retval = glDrawTexiOES; glDrawTexiOES = f; return retval;}
+	virtual glDrawTexxOES_client_proc_t set_glDrawTexxOES(glDrawTexxOES_client_proc_t f) { glDrawTexxOES_client_proc_t retval = glDrawTexxOES; glDrawTexxOES = f; return retval;}
+	virtual glDrawTexsvOES_client_proc_t set_glDrawTexsvOES(glDrawTexsvOES_client_proc_t f) { glDrawTexsvOES_client_proc_t retval = glDrawTexsvOES; glDrawTexsvOES = f; return retval;}
+	virtual glDrawTexivOES_client_proc_t set_glDrawTexivOES(glDrawTexivOES_client_proc_t f) { glDrawTexivOES_client_proc_t retval = glDrawTexivOES; glDrawTexivOES = f; return retval;}
+	virtual glDrawTexxvOES_client_proc_t set_glDrawTexxvOES(glDrawTexxvOES_client_proc_t f) { glDrawTexxvOES_client_proc_t retval = glDrawTexxvOES; glDrawTexxvOES = f; return retval;}
+	virtual glDrawTexfOES_client_proc_t set_glDrawTexfOES(glDrawTexfOES_client_proc_t f) { glDrawTexfOES_client_proc_t retval = glDrawTexfOES; glDrawTexfOES = f; return retval;}
+	virtual glDrawTexfvOES_client_proc_t set_glDrawTexfvOES(glDrawTexfvOES_client_proc_t f) { glDrawTexfvOES_client_proc_t retval = glDrawTexfvOES; glDrawTexfvOES = f; return retval;}
+	virtual glEGLImageTargetTexture2DOES_client_proc_t set_glEGLImageTargetTexture2DOES(glEGLImageTargetTexture2DOES_client_proc_t f) { glEGLImageTargetTexture2DOES_client_proc_t retval = glEGLImageTargetTexture2DOES; glEGLImageTargetTexture2DOES = f; return retval;}
+	virtual glEGLImageTargetRenderbufferStorageOES_client_proc_t set_glEGLImageTargetRenderbufferStorageOES(glEGLImageTargetRenderbufferStorageOES_client_proc_t f) { glEGLImageTargetRenderbufferStorageOES_client_proc_t retval = glEGLImageTargetRenderbufferStorageOES; glEGLImageTargetRenderbufferStorageOES = f; return retval;}
+	virtual glAlphaFuncxOES_client_proc_t set_glAlphaFuncxOES(glAlphaFuncxOES_client_proc_t f) { glAlphaFuncxOES_client_proc_t retval = glAlphaFuncxOES; glAlphaFuncxOES = f; return retval;}
+	virtual glClearColorxOES_client_proc_t set_glClearColorxOES(glClearColorxOES_client_proc_t f) { glClearColorxOES_client_proc_t retval = glClearColorxOES; glClearColorxOES = f; return retval;}
+	virtual glClearDepthxOES_client_proc_t set_glClearDepthxOES(glClearDepthxOES_client_proc_t f) { glClearDepthxOES_client_proc_t retval = glClearDepthxOES; glClearDepthxOES = f; return retval;}
+	virtual glClipPlanexOES_client_proc_t set_glClipPlanexOES(glClipPlanexOES_client_proc_t f) { glClipPlanexOES_client_proc_t retval = glClipPlanexOES; glClipPlanexOES = f; return retval;}
+	virtual glClipPlanexIMG_client_proc_t set_glClipPlanexIMG(glClipPlanexIMG_client_proc_t f) { glClipPlanexIMG_client_proc_t retval = glClipPlanexIMG; glClipPlanexIMG = f; return retval;}
+	virtual glColor4xOES_client_proc_t set_glColor4xOES(glColor4xOES_client_proc_t f) { glColor4xOES_client_proc_t retval = glColor4xOES; glColor4xOES = f; return retval;}
+	virtual glDepthRangexOES_client_proc_t set_glDepthRangexOES(glDepthRangexOES_client_proc_t f) { glDepthRangexOES_client_proc_t retval = glDepthRangexOES; glDepthRangexOES = f; return retval;}
+	virtual glFogxOES_client_proc_t set_glFogxOES(glFogxOES_client_proc_t f) { glFogxOES_client_proc_t retval = glFogxOES; glFogxOES = f; return retval;}
+	virtual glFogxvOES_client_proc_t set_glFogxvOES(glFogxvOES_client_proc_t f) { glFogxvOES_client_proc_t retval = glFogxvOES; glFogxvOES = f; return retval;}
+	virtual glFrustumxOES_client_proc_t set_glFrustumxOES(glFrustumxOES_client_proc_t f) { glFrustumxOES_client_proc_t retval = glFrustumxOES; glFrustumxOES = f; return retval;}
+	virtual glGetClipPlanexOES_client_proc_t set_glGetClipPlanexOES(glGetClipPlanexOES_client_proc_t f) { glGetClipPlanexOES_client_proc_t retval = glGetClipPlanexOES; glGetClipPlanexOES = f; return retval;}
+	virtual glGetClipPlanex_client_proc_t set_glGetClipPlanex(glGetClipPlanex_client_proc_t f) { glGetClipPlanex_client_proc_t retval = glGetClipPlanex; glGetClipPlanex = f; return retval;}
+	virtual glGetFixedvOES_client_proc_t set_glGetFixedvOES(glGetFixedvOES_client_proc_t f) { glGetFixedvOES_client_proc_t retval = glGetFixedvOES; glGetFixedvOES = f; return retval;}
+	virtual glGetLightxvOES_client_proc_t set_glGetLightxvOES(glGetLightxvOES_client_proc_t f) { glGetLightxvOES_client_proc_t retval = glGetLightxvOES; glGetLightxvOES = f; return retval;}
+	virtual glGetMaterialxvOES_client_proc_t set_glGetMaterialxvOES(glGetMaterialxvOES_client_proc_t f) { glGetMaterialxvOES_client_proc_t retval = glGetMaterialxvOES; glGetMaterialxvOES = f; return retval;}
+	virtual glGetTexEnvxvOES_client_proc_t set_glGetTexEnvxvOES(glGetTexEnvxvOES_client_proc_t f) { glGetTexEnvxvOES_client_proc_t retval = glGetTexEnvxvOES; glGetTexEnvxvOES = f; return retval;}
+	virtual glGetTexParameterxvOES_client_proc_t set_glGetTexParameterxvOES(glGetTexParameterxvOES_client_proc_t f) { glGetTexParameterxvOES_client_proc_t retval = glGetTexParameterxvOES; glGetTexParameterxvOES = f; return retval;}
+	virtual glLightModelxOES_client_proc_t set_glLightModelxOES(glLightModelxOES_client_proc_t f) { glLightModelxOES_client_proc_t retval = glLightModelxOES; glLightModelxOES = f; return retval;}
+	virtual glLightModelxvOES_client_proc_t set_glLightModelxvOES(glLightModelxvOES_client_proc_t f) { glLightModelxvOES_client_proc_t retval = glLightModelxvOES; glLightModelxvOES = f; return retval;}
+	virtual glLightxOES_client_proc_t set_glLightxOES(glLightxOES_client_proc_t f) { glLightxOES_client_proc_t retval = glLightxOES; glLightxOES = f; return retval;}
+	virtual glLightxvOES_client_proc_t set_glLightxvOES(glLightxvOES_client_proc_t f) { glLightxvOES_client_proc_t retval = glLightxvOES; glLightxvOES = f; return retval;}
+	virtual glLineWidthxOES_client_proc_t set_glLineWidthxOES(glLineWidthxOES_client_proc_t f) { glLineWidthxOES_client_proc_t retval = glLineWidthxOES; glLineWidthxOES = f; return retval;}
+	virtual glLoadMatrixxOES_client_proc_t set_glLoadMatrixxOES(glLoadMatrixxOES_client_proc_t f) { glLoadMatrixxOES_client_proc_t retval = glLoadMatrixxOES; glLoadMatrixxOES = f; return retval;}
+	virtual glMaterialxOES_client_proc_t set_glMaterialxOES(glMaterialxOES_client_proc_t f) { glMaterialxOES_client_proc_t retval = glMaterialxOES; glMaterialxOES = f; return retval;}
+	virtual glMaterialxvOES_client_proc_t set_glMaterialxvOES(glMaterialxvOES_client_proc_t f) { glMaterialxvOES_client_proc_t retval = glMaterialxvOES; glMaterialxvOES = f; return retval;}
+	virtual glMultMatrixxOES_client_proc_t set_glMultMatrixxOES(glMultMatrixxOES_client_proc_t f) { glMultMatrixxOES_client_proc_t retval = glMultMatrixxOES; glMultMatrixxOES = f; return retval;}
+	virtual glMultiTexCoord4xOES_client_proc_t set_glMultiTexCoord4xOES(glMultiTexCoord4xOES_client_proc_t f) { glMultiTexCoord4xOES_client_proc_t retval = glMultiTexCoord4xOES; glMultiTexCoord4xOES = f; return retval;}
+	virtual glNormal3xOES_client_proc_t set_glNormal3xOES(glNormal3xOES_client_proc_t f) { glNormal3xOES_client_proc_t retval = glNormal3xOES; glNormal3xOES = f; return retval;}
+	virtual glOrthoxOES_client_proc_t set_glOrthoxOES(glOrthoxOES_client_proc_t f) { glOrthoxOES_client_proc_t retval = glOrthoxOES; glOrthoxOES = f; return retval;}
+	virtual glPointParameterxOES_client_proc_t set_glPointParameterxOES(glPointParameterxOES_client_proc_t f) { glPointParameterxOES_client_proc_t retval = glPointParameterxOES; glPointParameterxOES = f; return retval;}
+	virtual glPointParameterxvOES_client_proc_t set_glPointParameterxvOES(glPointParameterxvOES_client_proc_t f) { glPointParameterxvOES_client_proc_t retval = glPointParameterxvOES; glPointParameterxvOES = f; return retval;}
+	virtual glPointSizexOES_client_proc_t set_glPointSizexOES(glPointSizexOES_client_proc_t f) { glPointSizexOES_client_proc_t retval = glPointSizexOES; glPointSizexOES = f; return retval;}
+	virtual glPolygonOffsetxOES_client_proc_t set_glPolygonOffsetxOES(glPolygonOffsetxOES_client_proc_t f) { glPolygonOffsetxOES_client_proc_t retval = glPolygonOffsetxOES; glPolygonOffsetxOES = f; return retval;}
+	virtual glRotatexOES_client_proc_t set_glRotatexOES(glRotatexOES_client_proc_t f) { glRotatexOES_client_proc_t retval = glRotatexOES; glRotatexOES = f; return retval;}
+	virtual glSampleCoveragexOES_client_proc_t set_glSampleCoveragexOES(glSampleCoveragexOES_client_proc_t f) { glSampleCoveragexOES_client_proc_t retval = glSampleCoveragexOES; glSampleCoveragexOES = f; return retval;}
+	virtual glScalexOES_client_proc_t set_glScalexOES(glScalexOES_client_proc_t f) { glScalexOES_client_proc_t retval = glScalexOES; glScalexOES = f; return retval;}
+	virtual glTexEnvxOES_client_proc_t set_glTexEnvxOES(glTexEnvxOES_client_proc_t f) { glTexEnvxOES_client_proc_t retval = glTexEnvxOES; glTexEnvxOES = f; return retval;}
+	virtual glTexEnvxvOES_client_proc_t set_glTexEnvxvOES(glTexEnvxvOES_client_proc_t f) { glTexEnvxvOES_client_proc_t retval = glTexEnvxvOES; glTexEnvxvOES = f; return retval;}
+	virtual glTexParameterxOES_client_proc_t set_glTexParameterxOES(glTexParameterxOES_client_proc_t f) { glTexParameterxOES_client_proc_t retval = glTexParameterxOES; glTexParameterxOES = f; return retval;}
+	virtual glTexParameterxvOES_client_proc_t set_glTexParameterxvOES(glTexParameterxvOES_client_proc_t f) { glTexParameterxvOES_client_proc_t retval = glTexParameterxvOES; glTexParameterxvOES = f; return retval;}
+	virtual glTranslatexOES_client_proc_t set_glTranslatexOES(glTranslatexOES_client_proc_t f) { glTranslatexOES_client_proc_t retval = glTranslatexOES; glTranslatexOES = f; return retval;}
+	virtual glIsRenderbufferOES_client_proc_t set_glIsRenderbufferOES(glIsRenderbufferOES_client_proc_t f) { glIsRenderbufferOES_client_proc_t retval = glIsRenderbufferOES; glIsRenderbufferOES = f; return retval;}
+	virtual glBindRenderbufferOES_client_proc_t set_glBindRenderbufferOES(glBindRenderbufferOES_client_proc_t f) { glBindRenderbufferOES_client_proc_t retval = glBindRenderbufferOES; glBindRenderbufferOES = f; return retval;}
+	virtual glDeleteRenderbuffersOES_client_proc_t set_glDeleteRenderbuffersOES(glDeleteRenderbuffersOES_client_proc_t f) { glDeleteRenderbuffersOES_client_proc_t retval = glDeleteRenderbuffersOES; glDeleteRenderbuffersOES = f; return retval;}
+	virtual glGenRenderbuffersOES_client_proc_t set_glGenRenderbuffersOES(glGenRenderbuffersOES_client_proc_t f) { glGenRenderbuffersOES_client_proc_t retval = glGenRenderbuffersOES; glGenRenderbuffersOES = f; return retval;}
+	virtual glRenderbufferStorageOES_client_proc_t set_glRenderbufferStorageOES(glRenderbufferStorageOES_client_proc_t f) { glRenderbufferStorageOES_client_proc_t retval = glRenderbufferStorageOES; glRenderbufferStorageOES = f; return retval;}
+	virtual glGetRenderbufferParameterivOES_client_proc_t set_glGetRenderbufferParameterivOES(glGetRenderbufferParameterivOES_client_proc_t f) { glGetRenderbufferParameterivOES_client_proc_t retval = glGetRenderbufferParameterivOES; glGetRenderbufferParameterivOES = f; return retval;}
+	virtual glIsFramebufferOES_client_proc_t set_glIsFramebufferOES(glIsFramebufferOES_client_proc_t f) { glIsFramebufferOES_client_proc_t retval = glIsFramebufferOES; glIsFramebufferOES = f; return retval;}
+	virtual glBindFramebufferOES_client_proc_t set_glBindFramebufferOES(glBindFramebufferOES_client_proc_t f) { glBindFramebufferOES_client_proc_t retval = glBindFramebufferOES; glBindFramebufferOES = f; return retval;}
+	virtual glDeleteFramebuffersOES_client_proc_t set_glDeleteFramebuffersOES(glDeleteFramebuffersOES_client_proc_t f) { glDeleteFramebuffersOES_client_proc_t retval = glDeleteFramebuffersOES; glDeleteFramebuffersOES = f; return retval;}
+	virtual glGenFramebuffersOES_client_proc_t set_glGenFramebuffersOES(glGenFramebuffersOES_client_proc_t f) { glGenFramebuffersOES_client_proc_t retval = glGenFramebuffersOES; glGenFramebuffersOES = f; return retval;}
+	virtual glCheckFramebufferStatusOES_client_proc_t set_glCheckFramebufferStatusOES(glCheckFramebufferStatusOES_client_proc_t f) { glCheckFramebufferStatusOES_client_proc_t retval = glCheckFramebufferStatusOES; glCheckFramebufferStatusOES = f; return retval;}
+	virtual glFramebufferRenderbufferOES_client_proc_t set_glFramebufferRenderbufferOES(glFramebufferRenderbufferOES_client_proc_t f) { glFramebufferRenderbufferOES_client_proc_t retval = glFramebufferRenderbufferOES; glFramebufferRenderbufferOES = f; return retval;}
+	virtual glFramebufferTexture2DOES_client_proc_t set_glFramebufferTexture2DOES(glFramebufferTexture2DOES_client_proc_t f) { glFramebufferTexture2DOES_client_proc_t retval = glFramebufferTexture2DOES; glFramebufferTexture2DOES = f; return retval;}
+	virtual glGetFramebufferAttachmentParameterivOES_client_proc_t set_glGetFramebufferAttachmentParameterivOES(glGetFramebufferAttachmentParameterivOES_client_proc_t f) { glGetFramebufferAttachmentParameterivOES_client_proc_t retval = glGetFramebufferAttachmentParameterivOES; glGetFramebufferAttachmentParameterivOES = f; return retval;}
+	virtual glGenerateMipmapOES_client_proc_t set_glGenerateMipmapOES(glGenerateMipmapOES_client_proc_t f) { glGenerateMipmapOES_client_proc_t retval = glGenerateMipmapOES; glGenerateMipmapOES = f; return retval;}
+	virtual glMapBufferOES_client_proc_t set_glMapBufferOES(glMapBufferOES_client_proc_t f) { glMapBufferOES_client_proc_t retval = glMapBufferOES; glMapBufferOES = f; return retval;}
+	virtual glUnmapBufferOES_client_proc_t set_glUnmapBufferOES(glUnmapBufferOES_client_proc_t f) { glUnmapBufferOES_client_proc_t retval = glUnmapBufferOES; glUnmapBufferOES = f; return retval;}
+	virtual glGetBufferPointervOES_client_proc_t set_glGetBufferPointervOES(glGetBufferPointervOES_client_proc_t f) { glGetBufferPointervOES_client_proc_t retval = glGetBufferPointervOES; glGetBufferPointervOES = f; return retval;}
+	virtual glCurrentPaletteMatrixOES_client_proc_t set_glCurrentPaletteMatrixOES(glCurrentPaletteMatrixOES_client_proc_t f) { glCurrentPaletteMatrixOES_client_proc_t retval = glCurrentPaletteMatrixOES; glCurrentPaletteMatrixOES = f; return retval;}
+	virtual glLoadPaletteFromModelViewMatrixOES_client_proc_t set_glLoadPaletteFromModelViewMatrixOES(glLoadPaletteFromModelViewMatrixOES_client_proc_t f) { glLoadPaletteFromModelViewMatrixOES_client_proc_t retval = glLoadPaletteFromModelViewMatrixOES; glLoadPaletteFromModelViewMatrixOES = f; return retval;}
+	virtual glMatrixIndexPointerOES_client_proc_t set_glMatrixIndexPointerOES(glMatrixIndexPointerOES_client_proc_t f) { glMatrixIndexPointerOES_client_proc_t retval = glMatrixIndexPointerOES; glMatrixIndexPointerOES = f; return retval;}
+	virtual glWeightPointerOES_client_proc_t set_glWeightPointerOES(glWeightPointerOES_client_proc_t f) { glWeightPointerOES_client_proc_t retval = glWeightPointerOES; glWeightPointerOES = f; return retval;}
+	virtual glQueryMatrixxOES_client_proc_t set_glQueryMatrixxOES(glQueryMatrixxOES_client_proc_t f) { glQueryMatrixxOES_client_proc_t retval = glQueryMatrixxOES; glQueryMatrixxOES = f; return retval;}
+	virtual glDepthRangefOES_client_proc_t set_glDepthRangefOES(glDepthRangefOES_client_proc_t f) { glDepthRangefOES_client_proc_t retval = glDepthRangefOES; glDepthRangefOES = f; return retval;}
+	virtual glFrustumfOES_client_proc_t set_glFrustumfOES(glFrustumfOES_client_proc_t f) { glFrustumfOES_client_proc_t retval = glFrustumfOES; glFrustumfOES = f; return retval;}
+	virtual glOrthofOES_client_proc_t set_glOrthofOES(glOrthofOES_client_proc_t f) { glOrthofOES_client_proc_t retval = glOrthofOES; glOrthofOES = f; return retval;}
+	virtual glClipPlanefOES_client_proc_t set_glClipPlanefOES(glClipPlanefOES_client_proc_t f) { glClipPlanefOES_client_proc_t retval = glClipPlanefOES; glClipPlanefOES = f; return retval;}
+	virtual glClipPlanefIMG_client_proc_t set_glClipPlanefIMG(glClipPlanefIMG_client_proc_t f) { glClipPlanefIMG_client_proc_t retval = glClipPlanefIMG; glClipPlanefIMG = f; return retval;}
+	virtual glGetClipPlanefOES_client_proc_t set_glGetClipPlanefOES(glGetClipPlanefOES_client_proc_t f) { glGetClipPlanefOES_client_proc_t retval = glGetClipPlanefOES; glGetClipPlanefOES = f; return retval;}
+	virtual glClearDepthfOES_client_proc_t set_glClearDepthfOES(glClearDepthfOES_client_proc_t f) { glClearDepthfOES_client_proc_t retval = glClearDepthfOES; glClearDepthfOES = f; return retval;}
+	virtual glTexGenfOES_client_proc_t set_glTexGenfOES(glTexGenfOES_client_proc_t f) { glTexGenfOES_client_proc_t retval = glTexGenfOES; glTexGenfOES = f; return retval;}
+	virtual glTexGenfvOES_client_proc_t set_glTexGenfvOES(glTexGenfvOES_client_proc_t f) { glTexGenfvOES_client_proc_t retval = glTexGenfvOES; glTexGenfvOES = f; return retval;}
+	virtual glTexGeniOES_client_proc_t set_glTexGeniOES(glTexGeniOES_client_proc_t f) { glTexGeniOES_client_proc_t retval = glTexGeniOES; glTexGeniOES = f; return retval;}
+	virtual glTexGenivOES_client_proc_t set_glTexGenivOES(glTexGenivOES_client_proc_t f) { glTexGenivOES_client_proc_t retval = glTexGenivOES; glTexGenivOES = f; return retval;}
+	virtual glTexGenxOES_client_proc_t set_glTexGenxOES(glTexGenxOES_client_proc_t f) { glTexGenxOES_client_proc_t retval = glTexGenxOES; glTexGenxOES = f; return retval;}
+	virtual glTexGenxvOES_client_proc_t set_glTexGenxvOES(glTexGenxvOES_client_proc_t f) { glTexGenxvOES_client_proc_t retval = glTexGenxvOES; glTexGenxvOES = f; return retval;}
+	virtual glGetTexGenfvOES_client_proc_t set_glGetTexGenfvOES(glGetTexGenfvOES_client_proc_t f) { glGetTexGenfvOES_client_proc_t retval = glGetTexGenfvOES; glGetTexGenfvOES = f; return retval;}
+	virtual glGetTexGenivOES_client_proc_t set_glGetTexGenivOES(glGetTexGenivOES_client_proc_t f) { glGetTexGenivOES_client_proc_t retval = glGetTexGenivOES; glGetTexGenivOES = f; return retval;}
+	virtual glGetTexGenxvOES_client_proc_t set_glGetTexGenxvOES(glGetTexGenxvOES_client_proc_t f) { glGetTexGenxvOES_client_proc_t retval = glGetTexGenxvOES; glGetTexGenxvOES = f; return retval;}
+	virtual glBindVertexArrayOES_client_proc_t set_glBindVertexArrayOES(glBindVertexArrayOES_client_proc_t f) { glBindVertexArrayOES_client_proc_t retval = glBindVertexArrayOES; glBindVertexArrayOES = f; return retval;}
+	virtual glDeleteVertexArraysOES_client_proc_t set_glDeleteVertexArraysOES(glDeleteVertexArraysOES_client_proc_t f) { glDeleteVertexArraysOES_client_proc_t retval = glDeleteVertexArraysOES; glDeleteVertexArraysOES = f; return retval;}
+	virtual glGenVertexArraysOES_client_proc_t set_glGenVertexArraysOES(glGenVertexArraysOES_client_proc_t f) { glGenVertexArraysOES_client_proc_t retval = glGenVertexArraysOES; glGenVertexArraysOES = f; return retval;}
+	virtual glIsVertexArrayOES_client_proc_t set_glIsVertexArrayOES(glIsVertexArrayOES_client_proc_t f) { glIsVertexArrayOES_client_proc_t retval = glIsVertexArrayOES; glIsVertexArrayOES = f; return retval;}
+	virtual glDiscardFramebufferEXT_client_proc_t set_glDiscardFramebufferEXT(glDiscardFramebufferEXT_client_proc_t f) { glDiscardFramebufferEXT_client_proc_t retval = glDiscardFramebufferEXT; glDiscardFramebufferEXT = f; return retval;}
+	virtual glMultiDrawArraysEXT_client_proc_t set_glMultiDrawArraysEXT(glMultiDrawArraysEXT_client_proc_t f) { glMultiDrawArraysEXT_client_proc_t retval = glMultiDrawArraysEXT; glMultiDrawArraysEXT = f; return retval;}
+	virtual glMultiDrawElementsEXT_client_proc_t set_glMultiDrawElementsEXT(glMultiDrawElementsEXT_client_proc_t f) { glMultiDrawElementsEXT_client_proc_t retval = glMultiDrawElementsEXT; glMultiDrawElementsEXT = f; return retval;}
+	virtual glMultiDrawArraysSUN_client_proc_t set_glMultiDrawArraysSUN(glMultiDrawArraysSUN_client_proc_t f) { glMultiDrawArraysSUN_client_proc_t retval = glMultiDrawArraysSUN; glMultiDrawArraysSUN = f; return retval;}
+	virtual glMultiDrawElementsSUN_client_proc_t set_glMultiDrawElementsSUN(glMultiDrawElementsSUN_client_proc_t f) { glMultiDrawElementsSUN_client_proc_t retval = glMultiDrawElementsSUN; glMultiDrawElementsSUN = f; return retval;}
+	virtual glRenderbufferStorageMultisampleIMG_client_proc_t set_glRenderbufferStorageMultisampleIMG(glRenderbufferStorageMultisampleIMG_client_proc_t f) { glRenderbufferStorageMultisampleIMG_client_proc_t retval = glRenderbufferStorageMultisampleIMG; glRenderbufferStorageMultisampleIMG = f; return retval;}
+	virtual glFramebufferTexture2DMultisampleIMG_client_proc_t set_glFramebufferTexture2DMultisampleIMG(glFramebufferTexture2DMultisampleIMG_client_proc_t f) { glFramebufferTexture2DMultisampleIMG_client_proc_t retval = glFramebufferTexture2DMultisampleIMG; glFramebufferTexture2DMultisampleIMG = f; return retval;}
+	virtual glDeleteFencesNV_client_proc_t set_glDeleteFencesNV(glDeleteFencesNV_client_proc_t f) { glDeleteFencesNV_client_proc_t retval = glDeleteFencesNV; glDeleteFencesNV = f; return retval;}
+	virtual glGenFencesNV_client_proc_t set_glGenFencesNV(glGenFencesNV_client_proc_t f) { glGenFencesNV_client_proc_t retval = glGenFencesNV; glGenFencesNV = f; return retval;}
+	virtual glIsFenceNV_client_proc_t set_glIsFenceNV(glIsFenceNV_client_proc_t f) { glIsFenceNV_client_proc_t retval = glIsFenceNV; glIsFenceNV = f; return retval;}
+	virtual glTestFenceNV_client_proc_t set_glTestFenceNV(glTestFenceNV_client_proc_t f) { glTestFenceNV_client_proc_t retval = glTestFenceNV; glTestFenceNV = f; return retval;}
+	virtual glGetFenceivNV_client_proc_t set_glGetFenceivNV(glGetFenceivNV_client_proc_t f) { glGetFenceivNV_client_proc_t retval = glGetFenceivNV; glGetFenceivNV = f; return retval;}
+	virtual glFinishFenceNV_client_proc_t set_glFinishFenceNV(glFinishFenceNV_client_proc_t f) { glFinishFenceNV_client_proc_t retval = glFinishFenceNV; glFinishFenceNV = f; return retval;}
+	virtual glSetFenceNV_client_proc_t set_glSetFenceNV(glSetFenceNV_client_proc_t f) { glSetFenceNV_client_proc_t retval = glSetFenceNV; glSetFenceNV = f; return retval;}
+	virtual glGetDriverControlsQCOM_client_proc_t set_glGetDriverControlsQCOM(glGetDriverControlsQCOM_client_proc_t f) { glGetDriverControlsQCOM_client_proc_t retval = glGetDriverControlsQCOM; glGetDriverControlsQCOM = f; return retval;}
+	virtual glGetDriverControlStringQCOM_client_proc_t set_glGetDriverControlStringQCOM(glGetDriverControlStringQCOM_client_proc_t f) { glGetDriverControlStringQCOM_client_proc_t retval = glGetDriverControlStringQCOM; glGetDriverControlStringQCOM = f; return retval;}
+	virtual glEnableDriverControlQCOM_client_proc_t set_glEnableDriverControlQCOM(glEnableDriverControlQCOM_client_proc_t f) { glEnableDriverControlQCOM_client_proc_t retval = glEnableDriverControlQCOM; glEnableDriverControlQCOM = f; return retval;}
+	virtual glDisableDriverControlQCOM_client_proc_t set_glDisableDriverControlQCOM(glDisableDriverControlQCOM_client_proc_t f) { glDisableDriverControlQCOM_client_proc_t retval = glDisableDriverControlQCOM; glDisableDriverControlQCOM = f; return retval;}
+	virtual glExtGetTexturesQCOM_client_proc_t set_glExtGetTexturesQCOM(glExtGetTexturesQCOM_client_proc_t f) { glExtGetTexturesQCOM_client_proc_t retval = glExtGetTexturesQCOM; glExtGetTexturesQCOM = f; return retval;}
+	virtual glExtGetBuffersQCOM_client_proc_t set_glExtGetBuffersQCOM(glExtGetBuffersQCOM_client_proc_t f) { glExtGetBuffersQCOM_client_proc_t retval = glExtGetBuffersQCOM; glExtGetBuffersQCOM = f; return retval;}
+	virtual glExtGetRenderbuffersQCOM_client_proc_t set_glExtGetRenderbuffersQCOM(glExtGetRenderbuffersQCOM_client_proc_t f) { glExtGetRenderbuffersQCOM_client_proc_t retval = glExtGetRenderbuffersQCOM; glExtGetRenderbuffersQCOM = f; return retval;}
+	virtual glExtGetFramebuffersQCOM_client_proc_t set_glExtGetFramebuffersQCOM(glExtGetFramebuffersQCOM_client_proc_t f) { glExtGetFramebuffersQCOM_client_proc_t retval = glExtGetFramebuffersQCOM; glExtGetFramebuffersQCOM = f; return retval;}
+	virtual glExtGetTexLevelParameterivQCOM_client_proc_t set_glExtGetTexLevelParameterivQCOM(glExtGetTexLevelParameterivQCOM_client_proc_t f) { glExtGetTexLevelParameterivQCOM_client_proc_t retval = glExtGetTexLevelParameterivQCOM; glExtGetTexLevelParameterivQCOM = f; return retval;}
+	virtual glExtTexObjectStateOverrideiQCOM_client_proc_t set_glExtTexObjectStateOverrideiQCOM(glExtTexObjectStateOverrideiQCOM_client_proc_t f) { glExtTexObjectStateOverrideiQCOM_client_proc_t retval = glExtTexObjectStateOverrideiQCOM; glExtTexObjectStateOverrideiQCOM = f; return retval;}
+	virtual glExtGetTexSubImageQCOM_client_proc_t set_glExtGetTexSubImageQCOM(glExtGetTexSubImageQCOM_client_proc_t f) { glExtGetTexSubImageQCOM_client_proc_t retval = glExtGetTexSubImageQCOM; glExtGetTexSubImageQCOM = f; return retval;}
+	virtual glExtGetBufferPointervQCOM_client_proc_t set_glExtGetBufferPointervQCOM(glExtGetBufferPointervQCOM_client_proc_t f) { glExtGetBufferPointervQCOM_client_proc_t retval = glExtGetBufferPointervQCOM; glExtGetBufferPointervQCOM = f; return retval;}
+	virtual glExtGetShadersQCOM_client_proc_t set_glExtGetShadersQCOM(glExtGetShadersQCOM_client_proc_t f) { glExtGetShadersQCOM_client_proc_t retval = glExtGetShadersQCOM; glExtGetShadersQCOM = f; return retval;}
+	virtual glExtGetProgramsQCOM_client_proc_t set_glExtGetProgramsQCOM(glExtGetProgramsQCOM_client_proc_t f) { glExtGetProgramsQCOM_client_proc_t retval = glExtGetProgramsQCOM; glExtGetProgramsQCOM = f; return retval;}
+	virtual glExtIsProgramBinaryQCOM_client_proc_t set_glExtIsProgramBinaryQCOM(glExtIsProgramBinaryQCOM_client_proc_t f) { glExtIsProgramBinaryQCOM_client_proc_t retval = glExtIsProgramBinaryQCOM; glExtIsProgramBinaryQCOM = f; return retval;}
+	virtual glExtGetProgramBinarySourceQCOM_client_proc_t set_glExtGetProgramBinarySourceQCOM(glExtGetProgramBinarySourceQCOM_client_proc_t f) { glExtGetProgramBinarySourceQCOM_client_proc_t retval = glExtGetProgramBinarySourceQCOM; glExtGetProgramBinarySourceQCOM = f; return retval;}
+	virtual glStartTilingQCOM_client_proc_t set_glStartTilingQCOM(glStartTilingQCOM_client_proc_t f) { glStartTilingQCOM_client_proc_t retval = glStartTilingQCOM; glStartTilingQCOM = f; return retval;}
+	virtual glEndTilingQCOM_client_proc_t set_glEndTilingQCOM(glEndTilingQCOM_client_proc_t f) { glEndTilingQCOM_client_proc_t retval = glEndTilingQCOM; glEndTilingQCOM = f; return retval;}
+	 virtual ~gl_client_context_t() {}
+
+	typedef gl_client_context_t *CONTEXT_ACCESSOR_TYPE(void);
+	static void setContextAccessor(CONTEXT_ACCESSOR_TYPE *f);
+	int initDispatchByName( void *(*getProc)(const char *name, void *userData), void *userData);
+	virtual void setError(unsigned int  error){};
+	virtual unsigned int getError(){ return 0; };
+};
+
+#endif
diff --git a/opengl/system/GLESv1_enc/gl_client_proc.h b/opengl/system/GLESv1_enc/gl_client_proc.h
new file mode 100644
index 0000000..a188657
--- /dev/null
+++ b/opengl/system/GLESv1_enc/gl_client_proc.h
@@ -0,0 +1,305 @@
+// Generated Code - DO NOT EDIT !!
+// generated by 'emugen'
+#ifndef __gl_client_proc_t_h
+#define __gl_client_proc_t_h
+
+
+
+#include "gl_types.h"
+#ifndef gl_APIENTRY
+#define gl_APIENTRY 
+#endif
+typedef void (gl_APIENTRY *glAlphaFunc_client_proc_t) (void * ctx, GLenum, GLclampf);
+typedef void (gl_APIENTRY *glClearColor_client_proc_t) (void * ctx, GLclampf, GLclampf, GLclampf, GLclampf);
+typedef void (gl_APIENTRY *glClearDepthf_client_proc_t) (void * ctx, GLclampf);
+typedef void (gl_APIENTRY *glClipPlanef_client_proc_t) (void * ctx, GLenum, const GLfloat*);
+typedef void (gl_APIENTRY *glColor4f_client_proc_t) (void * ctx, GLfloat, GLfloat, GLfloat, GLfloat);
+typedef void (gl_APIENTRY *glDepthRangef_client_proc_t) (void * ctx, GLclampf, GLclampf);
+typedef void (gl_APIENTRY *glFogf_client_proc_t) (void * ctx, GLenum, GLfloat);
+typedef void (gl_APIENTRY *glFogfv_client_proc_t) (void * ctx, GLenum, const GLfloat*);
+typedef void (gl_APIENTRY *glFrustumf_client_proc_t) (void * ctx, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+typedef void (gl_APIENTRY *glGetClipPlanef_client_proc_t) (void * ctx, GLenum, GLfloat*);
+typedef void (gl_APIENTRY *glGetFloatv_client_proc_t) (void * ctx, GLenum, GLfloat*);
+typedef void (gl_APIENTRY *glGetLightfv_client_proc_t) (void * ctx, GLenum, GLenum, GLfloat*);
+typedef void (gl_APIENTRY *glGetMaterialfv_client_proc_t) (void * ctx, GLenum, GLenum, GLfloat*);
+typedef void (gl_APIENTRY *glGetTexEnvfv_client_proc_t) (void * ctx, GLenum, GLenum, GLfloat*);
+typedef void (gl_APIENTRY *glGetTexParameterfv_client_proc_t) (void * ctx, GLenum, GLenum, GLfloat*);
+typedef void (gl_APIENTRY *glLightModelf_client_proc_t) (void * ctx, GLenum, GLfloat);
+typedef void (gl_APIENTRY *glLightModelfv_client_proc_t) (void * ctx, GLenum, const GLfloat*);
+typedef void (gl_APIENTRY *glLightf_client_proc_t) (void * ctx, GLenum, GLenum, GLfloat);
+typedef void (gl_APIENTRY *glLightfv_client_proc_t) (void * ctx, GLenum, GLenum, const GLfloat*);
+typedef void (gl_APIENTRY *glLineWidth_client_proc_t) (void * ctx, GLfloat);
+typedef void (gl_APIENTRY *glLoadMatrixf_client_proc_t) (void * ctx, const GLfloat*);
+typedef void (gl_APIENTRY *glMaterialf_client_proc_t) (void * ctx, GLenum, GLenum, GLfloat);
+typedef void (gl_APIENTRY *glMaterialfv_client_proc_t) (void * ctx, GLenum, GLenum, const GLfloat*);
+typedef void (gl_APIENTRY *glMultMatrixf_client_proc_t) (void * ctx, const GLfloat*);
+typedef void (gl_APIENTRY *glMultiTexCoord4f_client_proc_t) (void * ctx, GLenum, GLfloat, GLfloat, GLfloat, GLfloat);
+typedef void (gl_APIENTRY *glNormal3f_client_proc_t) (void * ctx, GLfloat, GLfloat, GLfloat);
+typedef void (gl_APIENTRY *glOrthof_client_proc_t) (void * ctx, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+typedef void (gl_APIENTRY *glPointParameterf_client_proc_t) (void * ctx, GLenum, GLfloat);
+typedef void (gl_APIENTRY *glPointParameterfv_client_proc_t) (void * ctx, GLenum, const GLfloat*);
+typedef void (gl_APIENTRY *glPointSize_client_proc_t) (void * ctx, GLfloat);
+typedef void (gl_APIENTRY *glPolygonOffset_client_proc_t) (void * ctx, GLfloat, GLfloat);
+typedef void (gl_APIENTRY *glRotatef_client_proc_t) (void * ctx, GLfloat, GLfloat, GLfloat, GLfloat);
+typedef void (gl_APIENTRY *glScalef_client_proc_t) (void * ctx, GLfloat, GLfloat, GLfloat);
+typedef void (gl_APIENTRY *glTexEnvf_client_proc_t) (void * ctx, GLenum, GLenum, GLfloat);
+typedef void (gl_APIENTRY *glTexEnvfv_client_proc_t) (void * ctx, GLenum, GLenum, const GLfloat*);
+typedef void (gl_APIENTRY *glTexParameterf_client_proc_t) (void * ctx, GLenum, GLenum, GLfloat);
+typedef void (gl_APIENTRY *glTexParameterfv_client_proc_t) (void * ctx, GLenum, GLenum, const GLfloat*);
+typedef void (gl_APIENTRY *glTranslatef_client_proc_t) (void * ctx, GLfloat, GLfloat, GLfloat);
+typedef void (gl_APIENTRY *glActiveTexture_client_proc_t) (void * ctx, GLenum);
+typedef void (gl_APIENTRY *glAlphaFuncx_client_proc_t) (void * ctx, GLenum, GLclampx);
+typedef void (gl_APIENTRY *glBindBuffer_client_proc_t) (void * ctx, GLenum, GLuint);
+typedef void (gl_APIENTRY *glBindTexture_client_proc_t) (void * ctx, GLenum, GLuint);
+typedef void (gl_APIENTRY *glBlendFunc_client_proc_t) (void * ctx, GLenum, GLenum);
+typedef void (gl_APIENTRY *glBufferData_client_proc_t) (void * ctx, GLenum, GLsizeiptr, const GLvoid*, GLenum);
+typedef void (gl_APIENTRY *glBufferSubData_client_proc_t) (void * ctx, GLenum, GLintptr, GLsizeiptr, const GLvoid*);
+typedef void (gl_APIENTRY *glClear_client_proc_t) (void * ctx, GLbitfield);
+typedef void (gl_APIENTRY *glClearColorx_client_proc_t) (void * ctx, GLclampx, GLclampx, GLclampx, GLclampx);
+typedef void (gl_APIENTRY *glClearDepthx_client_proc_t) (void * ctx, GLclampx);
+typedef void (gl_APIENTRY *glClearStencil_client_proc_t) (void * ctx, GLint);
+typedef void (gl_APIENTRY *glClientActiveTexture_client_proc_t) (void * ctx, GLenum);
+typedef void (gl_APIENTRY *glColor4ub_client_proc_t) (void * ctx, GLubyte, GLubyte, GLubyte, GLubyte);
+typedef void (gl_APIENTRY *glColor4x_client_proc_t) (void * ctx, GLfixed, GLfixed, GLfixed, GLfixed);
+typedef void (gl_APIENTRY *glColorMask_client_proc_t) (void * ctx, GLboolean, GLboolean, GLboolean, GLboolean);
+typedef void (gl_APIENTRY *glColorPointer_client_proc_t) (void * ctx, GLint, GLenum, GLsizei, const GLvoid*);
+typedef void (gl_APIENTRY *glCompressedTexImage2D_client_proc_t) (void * ctx, GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid*);
+typedef void (gl_APIENTRY *glCompressedTexSubImage2D_client_proc_t) (void * ctx, GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid*);
+typedef void (gl_APIENTRY *glCopyTexImage2D_client_proc_t) (void * ctx, GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint);
+typedef void (gl_APIENTRY *glCopyTexSubImage2D_client_proc_t) (void * ctx, GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei);
+typedef void (gl_APIENTRY *glCullFace_client_proc_t) (void * ctx, GLenum);
+typedef void (gl_APIENTRY *glDeleteBuffers_client_proc_t) (void * ctx, GLsizei, const GLuint*);
+typedef void (gl_APIENTRY *glDeleteTextures_client_proc_t) (void * ctx, GLsizei, const GLuint*);
+typedef void (gl_APIENTRY *glDepthFunc_client_proc_t) (void * ctx, GLenum);
+typedef void (gl_APIENTRY *glDepthMask_client_proc_t) (void * ctx, GLboolean);
+typedef void (gl_APIENTRY *glDepthRangex_client_proc_t) (void * ctx, GLclampx, GLclampx);
+typedef void (gl_APIENTRY *glDisable_client_proc_t) (void * ctx, GLenum);
+typedef void (gl_APIENTRY *glDisableClientState_client_proc_t) (void * ctx, GLenum);
+typedef void (gl_APIENTRY *glDrawArrays_client_proc_t) (void * ctx, GLenum, GLint, GLsizei);
+typedef void (gl_APIENTRY *glDrawElements_client_proc_t) (void * ctx, GLenum, GLsizei, GLenum, const GLvoid*);
+typedef void (gl_APIENTRY *glEnable_client_proc_t) (void * ctx, GLenum);
+typedef void (gl_APIENTRY *glEnableClientState_client_proc_t) (void * ctx, GLenum);
+typedef void (gl_APIENTRY *glFinish_client_proc_t) (void * ctx);
+typedef void (gl_APIENTRY *glFlush_client_proc_t) (void * ctx);
+typedef void (gl_APIENTRY *glFogx_client_proc_t) (void * ctx, GLenum, GLfixed);
+typedef void (gl_APIENTRY *glFogxv_client_proc_t) (void * ctx, GLenum, const GLfixed*);
+typedef void (gl_APIENTRY *glFrontFace_client_proc_t) (void * ctx, GLenum);
+typedef void (gl_APIENTRY *glFrustumx_client_proc_t) (void * ctx, GLfixed, GLfixed, GLfixed, GLfixed, GLfixed, GLfixed);
+typedef void (gl_APIENTRY *glGetBooleanv_client_proc_t) (void * ctx, GLenum, GLboolean*);
+typedef void (gl_APIENTRY *glGetBufferParameteriv_client_proc_t) (void * ctx, GLenum, GLenum, GLint*);
+typedef void (gl_APIENTRY *glClipPlanex_client_proc_t) (void * ctx, GLenum, const GLfixed*);
+typedef void (gl_APIENTRY *glGenBuffers_client_proc_t) (void * ctx, GLsizei, GLuint*);
+typedef void (gl_APIENTRY *glGenTextures_client_proc_t) (void * ctx, GLsizei, GLuint*);
+typedef GLenum (gl_APIENTRY *glGetError_client_proc_t) (void * ctx);
+typedef void (gl_APIENTRY *glGetFixedv_client_proc_t) (void * ctx, GLenum, GLfixed*);
+typedef void (gl_APIENTRY *glGetIntegerv_client_proc_t) (void * ctx, GLenum, GLint*);
+typedef void (gl_APIENTRY *glGetLightxv_client_proc_t) (void * ctx, GLenum, GLenum, GLfixed*);
+typedef void (gl_APIENTRY *glGetMaterialxv_client_proc_t) (void * ctx, GLenum, GLenum, GLfixed*);
+typedef void (gl_APIENTRY *glGetPointerv_client_proc_t) (void * ctx, GLenum, GLvoid**);
+typedef const GLubyte* (gl_APIENTRY *glGetString_client_proc_t) (void * ctx, GLenum);
+typedef void (gl_APIENTRY *glGetTexEnviv_client_proc_t) (void * ctx, GLenum, GLenum, GLint*);
+typedef void (gl_APIENTRY *glGetTexEnvxv_client_proc_t) (void * ctx, GLenum, GLenum, GLfixed*);
+typedef void (gl_APIENTRY *glGetTexParameteriv_client_proc_t) (void * ctx, GLenum, GLenum, GLint*);
+typedef void (gl_APIENTRY *glGetTexParameterxv_client_proc_t) (void * ctx, GLenum, GLenum, GLfixed*);
+typedef void (gl_APIENTRY *glHint_client_proc_t) (void * ctx, GLenum, GLenum);
+typedef GLboolean (gl_APIENTRY *glIsBuffer_client_proc_t) (void * ctx, GLuint);
+typedef GLboolean (gl_APIENTRY *glIsEnabled_client_proc_t) (void * ctx, GLenum);
+typedef GLboolean (gl_APIENTRY *glIsTexture_client_proc_t) (void * ctx, GLuint);
+typedef void (gl_APIENTRY *glLightModelx_client_proc_t) (void * ctx, GLenum, GLfixed);
+typedef void (gl_APIENTRY *glLightModelxv_client_proc_t) (void * ctx, GLenum, const GLfixed*);
+typedef void (gl_APIENTRY *glLightx_client_proc_t) (void * ctx, GLenum, GLenum, GLfixed);
+typedef void (gl_APIENTRY *glLightxv_client_proc_t) (void * ctx, GLenum, GLenum, const GLfixed*);
+typedef void (gl_APIENTRY *glLineWidthx_client_proc_t) (void * ctx, GLfixed);
+typedef void (gl_APIENTRY *glLoadIdentity_client_proc_t) (void * ctx);
+typedef void (gl_APIENTRY *glLoadMatrixx_client_proc_t) (void * ctx, const GLfixed*);
+typedef void (gl_APIENTRY *glLogicOp_client_proc_t) (void * ctx, GLenum);
+typedef void (gl_APIENTRY *glMaterialx_client_proc_t) (void * ctx, GLenum, GLenum, GLfixed);
+typedef void (gl_APIENTRY *glMaterialxv_client_proc_t) (void * ctx, GLenum, GLenum, const GLfixed*);
+typedef void (gl_APIENTRY *glMatrixMode_client_proc_t) (void * ctx, GLenum);
+typedef void (gl_APIENTRY *glMultMatrixx_client_proc_t) (void * ctx, const GLfixed*);
+typedef void (gl_APIENTRY *glMultiTexCoord4x_client_proc_t) (void * ctx, GLenum, GLfixed, GLfixed, GLfixed, GLfixed);
+typedef void (gl_APIENTRY *glNormal3x_client_proc_t) (void * ctx, GLfixed, GLfixed, GLfixed);
+typedef void (gl_APIENTRY *glNormalPointer_client_proc_t) (void * ctx, GLenum, GLsizei, const GLvoid*);
+typedef void (gl_APIENTRY *glOrthox_client_proc_t) (void * ctx, GLfixed, GLfixed, GLfixed, GLfixed, GLfixed, GLfixed);
+typedef void (gl_APIENTRY *glPixelStorei_client_proc_t) (void * ctx, GLenum, GLint);
+typedef void (gl_APIENTRY *glPointParameterx_client_proc_t) (void * ctx, GLenum, GLfixed);
+typedef void (gl_APIENTRY *glPointParameterxv_client_proc_t) (void * ctx, GLenum, const GLfixed*);
+typedef void (gl_APIENTRY *glPointSizex_client_proc_t) (void * ctx, GLfixed);
+typedef void (gl_APIENTRY *glPolygonOffsetx_client_proc_t) (void * ctx, GLfixed, GLfixed);
+typedef void (gl_APIENTRY *glPopMatrix_client_proc_t) (void * ctx);
+typedef void (gl_APIENTRY *glPushMatrix_client_proc_t) (void * ctx);
+typedef void (gl_APIENTRY *glReadPixels_client_proc_t) (void * ctx, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, GLvoid*);
+typedef void (gl_APIENTRY *glRotatex_client_proc_t) (void * ctx, GLfixed, GLfixed, GLfixed, GLfixed);
+typedef void (gl_APIENTRY *glSampleCoverage_client_proc_t) (void * ctx, GLclampf, GLboolean);
+typedef void (gl_APIENTRY *glSampleCoveragex_client_proc_t) (void * ctx, GLclampx, GLboolean);
+typedef void (gl_APIENTRY *glScalex_client_proc_t) (void * ctx, GLfixed, GLfixed, GLfixed);
+typedef void (gl_APIENTRY *glScissor_client_proc_t) (void * ctx, GLint, GLint, GLsizei, GLsizei);
+typedef void (gl_APIENTRY *glShadeModel_client_proc_t) (void * ctx, GLenum);
+typedef void (gl_APIENTRY *glStencilFunc_client_proc_t) (void * ctx, GLenum, GLint, GLuint);
+typedef void (gl_APIENTRY *glStencilMask_client_proc_t) (void * ctx, GLuint);
+typedef void (gl_APIENTRY *glStencilOp_client_proc_t) (void * ctx, GLenum, GLenum, GLenum);
+typedef void (gl_APIENTRY *glTexCoordPointer_client_proc_t) (void * ctx, GLint, GLenum, GLsizei, const GLvoid*);
+typedef void (gl_APIENTRY *glTexEnvi_client_proc_t) (void * ctx, GLenum, GLenum, GLint);
+typedef void (gl_APIENTRY *glTexEnvx_client_proc_t) (void * ctx, GLenum, GLenum, GLfixed);
+typedef void (gl_APIENTRY *glTexEnviv_client_proc_t) (void * ctx, GLenum, GLenum, const GLint*);
+typedef void (gl_APIENTRY *glTexEnvxv_client_proc_t) (void * ctx, GLenum, GLenum, const GLfixed*);
+typedef void (gl_APIENTRY *glTexImage2D_client_proc_t) (void * ctx, GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid*);
+typedef void (gl_APIENTRY *glTexParameteri_client_proc_t) (void * ctx, GLenum, GLenum, GLint);
+typedef void (gl_APIENTRY *glTexParameterx_client_proc_t) (void * ctx, GLenum, GLenum, GLfixed);
+typedef void (gl_APIENTRY *glTexParameteriv_client_proc_t) (void * ctx, GLenum, GLenum, const GLint*);
+typedef void (gl_APIENTRY *glTexParameterxv_client_proc_t) (void * ctx, GLenum, GLenum, const GLfixed*);
+typedef void (gl_APIENTRY *glTexSubImage2D_client_proc_t) (void * ctx, GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid*);
+typedef void (gl_APIENTRY *glTranslatex_client_proc_t) (void * ctx, GLfixed, GLfixed, GLfixed);
+typedef void (gl_APIENTRY *glVertexPointer_client_proc_t) (void * ctx, GLint, GLenum, GLsizei, const GLvoid*);
+typedef void (gl_APIENTRY *glViewport_client_proc_t) (void * ctx, GLint, GLint, GLsizei, GLsizei);
+typedef void (gl_APIENTRY *glPointSizePointerOES_client_proc_t) (void * ctx, GLenum, GLsizei, const GLvoid*);
+typedef void (gl_APIENTRY *glVertexPointerOffset_client_proc_t) (void * ctx, GLint, GLenum, GLsizei, GLuint);
+typedef void (gl_APIENTRY *glColorPointerOffset_client_proc_t) (void * ctx, GLint, GLenum, GLsizei, GLuint);
+typedef void (gl_APIENTRY *glNormalPointerOffset_client_proc_t) (void * ctx, GLenum, GLsizei, GLuint);
+typedef void (gl_APIENTRY *glPointSizePointerOffset_client_proc_t) (void * ctx, GLenum, GLsizei, GLuint);
+typedef void (gl_APIENTRY *glTexCoordPointerOffset_client_proc_t) (void * ctx, GLint, GLenum, GLsizei, GLuint);
+typedef void (gl_APIENTRY *glWeightPointerOffset_client_proc_t) (void * ctx, GLint, GLenum, GLsizei, GLuint);
+typedef void (gl_APIENTRY *glMatrixIndexPointerOffset_client_proc_t) (void * ctx, GLint, GLenum, GLsizei, GLuint);
+typedef void (gl_APIENTRY *glVertexPointerData_client_proc_t) (void * ctx, GLint, GLenum, GLsizei, void*, GLuint);
+typedef void (gl_APIENTRY *glColorPointerData_client_proc_t) (void * ctx, GLint, GLenum, GLsizei, void*, GLuint);
+typedef void (gl_APIENTRY *glNormalPointerData_client_proc_t) (void * ctx, GLenum, GLsizei, void*, GLuint);
+typedef void (gl_APIENTRY *glTexCoordPointerData_client_proc_t) (void * ctx, GLint, GLint, GLenum, GLsizei, void*, GLuint);
+typedef void (gl_APIENTRY *glPointSizePointerData_client_proc_t) (void * ctx, GLenum, GLsizei, void*, GLuint);
+typedef void (gl_APIENTRY *glWeightPointerData_client_proc_t) (void * ctx, GLint, GLenum, GLsizei, void*, GLuint);
+typedef void (gl_APIENTRY *glMatrixIndexPointerData_client_proc_t) (void * ctx, GLint, GLenum, GLsizei, void*, GLuint);
+typedef void (gl_APIENTRY *glDrawElementsOffset_client_proc_t) (void * ctx, GLenum, GLsizei, GLenum, GLuint);
+typedef void (gl_APIENTRY *glDrawElementsData_client_proc_t) (void * ctx, GLenum, GLsizei, GLenum, void*, GLuint);
+typedef void (gl_APIENTRY *glGetCompressedTextureFormats_client_proc_t) (void * ctx, int, GLint*);
+typedef int (gl_APIENTRY *glFinishRoundTrip_client_proc_t) (void * ctx);
+typedef void (gl_APIENTRY *glBlendEquationSeparateOES_client_proc_t) (void * ctx, GLenum, GLenum);
+typedef void (gl_APIENTRY *glBlendFuncSeparateOES_client_proc_t) (void * ctx, GLenum, GLenum, GLenum, GLenum);
+typedef void (gl_APIENTRY *glBlendEquationOES_client_proc_t) (void * ctx, GLenum);
+typedef void (gl_APIENTRY *glDrawTexsOES_client_proc_t) (void * ctx, GLshort, GLshort, GLshort, GLshort, GLshort);
+typedef void (gl_APIENTRY *glDrawTexiOES_client_proc_t) (void * ctx, GLint, GLint, GLint, GLint, GLint);
+typedef void (gl_APIENTRY *glDrawTexxOES_client_proc_t) (void * ctx, GLfixed, GLfixed, GLfixed, GLfixed, GLfixed);
+typedef void (gl_APIENTRY *glDrawTexsvOES_client_proc_t) (void * ctx, const GLshort*);
+typedef void (gl_APIENTRY *glDrawTexivOES_client_proc_t) (void * ctx, const GLint*);
+typedef void (gl_APIENTRY *glDrawTexxvOES_client_proc_t) (void * ctx, const GLfixed*);
+typedef void (gl_APIENTRY *glDrawTexfOES_client_proc_t) (void * ctx, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+typedef void (gl_APIENTRY *glDrawTexfvOES_client_proc_t) (void * ctx, const GLfloat*);
+typedef void (gl_APIENTRY *glEGLImageTargetTexture2DOES_client_proc_t) (void * ctx, GLenum, GLeglImageOES);
+typedef void (gl_APIENTRY *glEGLImageTargetRenderbufferStorageOES_client_proc_t) (void * ctx, GLenum, GLeglImageOES);
+typedef void (gl_APIENTRY *glAlphaFuncxOES_client_proc_t) (void * ctx, GLenum, GLclampx);
+typedef void (gl_APIENTRY *glClearColorxOES_client_proc_t) (void * ctx, GLclampx, GLclampx, GLclampx, GLclampx);
+typedef void (gl_APIENTRY *glClearDepthxOES_client_proc_t) (void * ctx, GLclampx);
+typedef void (gl_APIENTRY *glClipPlanexOES_client_proc_t) (void * ctx, GLenum, const GLfixed*);
+typedef void (gl_APIENTRY *glClipPlanexIMG_client_proc_t) (void * ctx, GLenum, const GLfixed*);
+typedef void (gl_APIENTRY *glColor4xOES_client_proc_t) (void * ctx, GLfixed, GLfixed, GLfixed, GLfixed);
+typedef void (gl_APIENTRY *glDepthRangexOES_client_proc_t) (void * ctx, GLclampx, GLclampx);
+typedef void (gl_APIENTRY *glFogxOES_client_proc_t) (void * ctx, GLenum, GLfixed);
+typedef void (gl_APIENTRY *glFogxvOES_client_proc_t) (void * ctx, GLenum, const GLfixed*);
+typedef void (gl_APIENTRY *glFrustumxOES_client_proc_t) (void * ctx, GLfixed, GLfixed, GLfixed, GLfixed, GLfixed, GLfixed);
+typedef void (gl_APIENTRY *glGetClipPlanexOES_client_proc_t) (void * ctx, GLenum, GLfixed*);
+typedef void (gl_APIENTRY *glGetClipPlanex_client_proc_t) (void * ctx, GLenum, GLfixed*);
+typedef void (gl_APIENTRY *glGetFixedvOES_client_proc_t) (void * ctx, GLenum, GLfixed*);
+typedef void (gl_APIENTRY *glGetLightxvOES_client_proc_t) (void * ctx, GLenum, GLenum, GLfixed*);
+typedef void (gl_APIENTRY *glGetMaterialxvOES_client_proc_t) (void * ctx, GLenum, GLenum, GLfixed*);
+typedef void (gl_APIENTRY *glGetTexEnvxvOES_client_proc_t) (void * ctx, GLenum, GLenum, GLfixed*);
+typedef void (gl_APIENTRY *glGetTexParameterxvOES_client_proc_t) (void * ctx, GLenum, GLenum, GLfixed*);
+typedef void (gl_APIENTRY *glLightModelxOES_client_proc_t) (void * ctx, GLenum, GLfixed);
+typedef void (gl_APIENTRY *glLightModelxvOES_client_proc_t) (void * ctx, GLenum, const GLfixed*);
+typedef void (gl_APIENTRY *glLightxOES_client_proc_t) (void * ctx, GLenum, GLenum, GLfixed);
+typedef void (gl_APIENTRY *glLightxvOES_client_proc_t) (void * ctx, GLenum, GLenum, const GLfixed*);
+typedef void (gl_APIENTRY *glLineWidthxOES_client_proc_t) (void * ctx, GLfixed);
+typedef void (gl_APIENTRY *glLoadMatrixxOES_client_proc_t) (void * ctx, const GLfixed*);
+typedef void (gl_APIENTRY *glMaterialxOES_client_proc_t) (void * ctx, GLenum, GLenum, GLfixed);
+typedef void (gl_APIENTRY *glMaterialxvOES_client_proc_t) (void * ctx, GLenum, GLenum, const GLfixed*);
+typedef void (gl_APIENTRY *glMultMatrixxOES_client_proc_t) (void * ctx, const GLfixed*);
+typedef void (gl_APIENTRY *glMultiTexCoord4xOES_client_proc_t) (void * ctx, GLenum, GLfixed, GLfixed, GLfixed, GLfixed);
+typedef void (gl_APIENTRY *glNormal3xOES_client_proc_t) (void * ctx, GLfixed, GLfixed, GLfixed);
+typedef void (gl_APIENTRY *glOrthoxOES_client_proc_t) (void * ctx, GLfixed, GLfixed, GLfixed, GLfixed, GLfixed, GLfixed);
+typedef void (gl_APIENTRY *glPointParameterxOES_client_proc_t) (void * ctx, GLenum, GLfixed);
+typedef void (gl_APIENTRY *glPointParameterxvOES_client_proc_t) (void * ctx, GLenum, const GLfixed*);
+typedef void (gl_APIENTRY *glPointSizexOES_client_proc_t) (void * ctx, GLfixed);
+typedef void (gl_APIENTRY *glPolygonOffsetxOES_client_proc_t) (void * ctx, GLfixed, GLfixed);
+typedef void (gl_APIENTRY *glRotatexOES_client_proc_t) (void * ctx, GLfixed, GLfixed, GLfixed, GLfixed);
+typedef void (gl_APIENTRY *glSampleCoveragexOES_client_proc_t) (void * ctx, GLclampx, GLboolean);
+typedef void (gl_APIENTRY *glScalexOES_client_proc_t) (void * ctx, GLfixed, GLfixed, GLfixed);
+typedef void (gl_APIENTRY *glTexEnvxOES_client_proc_t) (void * ctx, GLenum, GLenum, GLfixed);
+typedef void (gl_APIENTRY *glTexEnvxvOES_client_proc_t) (void * ctx, GLenum, GLenum, const GLfixed*);
+typedef void (gl_APIENTRY *glTexParameterxOES_client_proc_t) (void * ctx, GLenum, GLenum, GLfixed);
+typedef void (gl_APIENTRY *glTexParameterxvOES_client_proc_t) (void * ctx, GLenum, GLenum, const GLfixed*);
+typedef void (gl_APIENTRY *glTranslatexOES_client_proc_t) (void * ctx, GLfixed, GLfixed, GLfixed);
+typedef GLboolean (gl_APIENTRY *glIsRenderbufferOES_client_proc_t) (void * ctx, GLuint);
+typedef void (gl_APIENTRY *glBindRenderbufferOES_client_proc_t) (void * ctx, GLenum, GLuint);
+typedef void (gl_APIENTRY *glDeleteRenderbuffersOES_client_proc_t) (void * ctx, GLsizei, const GLuint*);
+typedef void (gl_APIENTRY *glGenRenderbuffersOES_client_proc_t) (void * ctx, GLsizei, GLuint*);
+typedef void (gl_APIENTRY *glRenderbufferStorageOES_client_proc_t) (void * ctx, GLenum, GLenum, GLsizei, GLsizei);
+typedef void (gl_APIENTRY *glGetRenderbufferParameterivOES_client_proc_t) (void * ctx, GLenum, GLenum, GLint*);
+typedef GLboolean (gl_APIENTRY *glIsFramebufferOES_client_proc_t) (void * ctx, GLuint);
+typedef void (gl_APIENTRY *glBindFramebufferOES_client_proc_t) (void * ctx, GLenum, GLuint);
+typedef void (gl_APIENTRY *glDeleteFramebuffersOES_client_proc_t) (void * ctx, GLsizei, const GLuint*);
+typedef void (gl_APIENTRY *glGenFramebuffersOES_client_proc_t) (void * ctx, GLsizei, GLuint*);
+typedef GLenum (gl_APIENTRY *glCheckFramebufferStatusOES_client_proc_t) (void * ctx, GLenum);
+typedef void (gl_APIENTRY *glFramebufferRenderbufferOES_client_proc_t) (void * ctx, GLenum, GLenum, GLenum, GLuint);
+typedef void (gl_APIENTRY *glFramebufferTexture2DOES_client_proc_t) (void * ctx, GLenum, GLenum, GLenum, GLuint, GLint);
+typedef void (gl_APIENTRY *glGetFramebufferAttachmentParameterivOES_client_proc_t) (void * ctx, GLenum, GLenum, GLenum, GLint*);
+typedef void (gl_APIENTRY *glGenerateMipmapOES_client_proc_t) (void * ctx, GLenum);
+typedef void* (gl_APIENTRY *glMapBufferOES_client_proc_t) (void * ctx, GLenum, GLenum);
+typedef GLboolean (gl_APIENTRY *glUnmapBufferOES_client_proc_t) (void * ctx, GLenum);
+typedef void (gl_APIENTRY *glGetBufferPointervOES_client_proc_t) (void * ctx, GLenum, GLenum, GLvoid**);
+typedef void (gl_APIENTRY *glCurrentPaletteMatrixOES_client_proc_t) (void * ctx, GLuint);
+typedef void (gl_APIENTRY *glLoadPaletteFromModelViewMatrixOES_client_proc_t) (void * ctx);
+typedef void (gl_APIENTRY *glMatrixIndexPointerOES_client_proc_t) (void * ctx, GLint, GLenum, GLsizei, const GLvoid*);
+typedef void (gl_APIENTRY *glWeightPointerOES_client_proc_t) (void * ctx, GLint, GLenum, GLsizei, const GLvoid*);
+typedef GLbitfield (gl_APIENTRY *glQueryMatrixxOES_client_proc_t) (void * ctx, GLfixed*, GLint*);
+typedef void (gl_APIENTRY *glDepthRangefOES_client_proc_t) (void * ctx, GLclampf, GLclampf);
+typedef void (gl_APIENTRY *glFrustumfOES_client_proc_t) (void * ctx, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+typedef void (gl_APIENTRY *glOrthofOES_client_proc_t) (void * ctx, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+typedef void (gl_APIENTRY *glClipPlanefOES_client_proc_t) (void * ctx, GLenum, const GLfloat*);
+typedef void (gl_APIENTRY *glClipPlanefIMG_client_proc_t) (void * ctx, GLenum, const GLfloat*);
+typedef void (gl_APIENTRY *glGetClipPlanefOES_client_proc_t) (void * ctx, GLenum, GLfloat*);
+typedef void (gl_APIENTRY *glClearDepthfOES_client_proc_t) (void * ctx, GLclampf);
+typedef void (gl_APIENTRY *glTexGenfOES_client_proc_t) (void * ctx, GLenum, GLenum, GLfloat);
+typedef void (gl_APIENTRY *glTexGenfvOES_client_proc_t) (void * ctx, GLenum, GLenum, const GLfloat*);
+typedef void (gl_APIENTRY *glTexGeniOES_client_proc_t) (void * ctx, GLenum, GLenum, GLint);
+typedef void (gl_APIENTRY *glTexGenivOES_client_proc_t) (void * ctx, GLenum, GLenum, const GLint*);
+typedef void (gl_APIENTRY *glTexGenxOES_client_proc_t) (void * ctx, GLenum, GLenum, GLfixed);
+typedef void (gl_APIENTRY *glTexGenxvOES_client_proc_t) (void * ctx, GLenum, GLenum, const GLfixed*);
+typedef void (gl_APIENTRY *glGetTexGenfvOES_client_proc_t) (void * ctx, GLenum, GLenum, GLfloat*);
+typedef void (gl_APIENTRY *glGetTexGenivOES_client_proc_t) (void * ctx, GLenum, GLenum, GLint*);
+typedef void (gl_APIENTRY *glGetTexGenxvOES_client_proc_t) (void * ctx, GLenum, GLenum, GLfixed*);
+typedef void (gl_APIENTRY *glBindVertexArrayOES_client_proc_t) (void * ctx, GLuint);
+typedef void (gl_APIENTRY *glDeleteVertexArraysOES_client_proc_t) (void * ctx, GLsizei, const GLuint*);
+typedef void (gl_APIENTRY *glGenVertexArraysOES_client_proc_t) (void * ctx, GLsizei, GLuint*);
+typedef GLboolean (gl_APIENTRY *glIsVertexArrayOES_client_proc_t) (void * ctx, GLuint);
+typedef void (gl_APIENTRY *glDiscardFramebufferEXT_client_proc_t) (void * ctx, GLenum, GLsizei, const GLenum*);
+typedef void (gl_APIENTRY *glMultiDrawArraysEXT_client_proc_t) (void * ctx, GLenum, GLint*, GLsizei*, GLsizei);
+typedef void (gl_APIENTRY *glMultiDrawElementsEXT_client_proc_t) (void * ctx, GLenum, const GLsizei*, GLenum, const GLvoid**, GLsizei);
+typedef void (gl_APIENTRY *glMultiDrawArraysSUN_client_proc_t) (void * ctx, GLenum, GLint*, GLsizei*, GLsizei);
+typedef void (gl_APIENTRY *glMultiDrawElementsSUN_client_proc_t) (void * ctx, GLenum, const GLsizei*, GLenum, const GLvoid**, GLsizei);
+typedef void (gl_APIENTRY *glRenderbufferStorageMultisampleIMG_client_proc_t) (void * ctx, GLenum, GLsizei, GLenum, GLsizei, GLsizei);
+typedef void (gl_APIENTRY *glFramebufferTexture2DMultisampleIMG_client_proc_t) (void * ctx, GLenum, GLenum, GLenum, GLuint, GLint, GLsizei);
+typedef void (gl_APIENTRY *glDeleteFencesNV_client_proc_t) (void * ctx, GLsizei, const GLuint*);
+typedef void (gl_APIENTRY *glGenFencesNV_client_proc_t) (void * ctx, GLsizei, GLuint*);
+typedef GLboolean (gl_APIENTRY *glIsFenceNV_client_proc_t) (void * ctx, GLuint);
+typedef GLboolean (gl_APIENTRY *glTestFenceNV_client_proc_t) (void * ctx, GLuint);
+typedef void (gl_APIENTRY *glGetFenceivNV_client_proc_t) (void * ctx, GLuint, GLenum, GLint*);
+typedef void (gl_APIENTRY *glFinishFenceNV_client_proc_t) (void * ctx, GLuint);
+typedef void (gl_APIENTRY *glSetFenceNV_client_proc_t) (void * ctx, GLuint, GLenum);
+typedef void (gl_APIENTRY *glGetDriverControlsQCOM_client_proc_t) (void * ctx, GLint*, GLsizei, GLuint*);
+typedef void (gl_APIENTRY *glGetDriverControlStringQCOM_client_proc_t) (void * ctx, GLuint, GLsizei, GLsizei*, GLchar*);
+typedef void (gl_APIENTRY *glEnableDriverControlQCOM_client_proc_t) (void * ctx, GLuint);
+typedef void (gl_APIENTRY *glDisableDriverControlQCOM_client_proc_t) (void * ctx, GLuint);
+typedef void (gl_APIENTRY *glExtGetTexturesQCOM_client_proc_t) (void * ctx, GLuint*, GLint, GLint*);
+typedef void (gl_APIENTRY *glExtGetBuffersQCOM_client_proc_t) (void * ctx, GLuint*, GLint, GLint*);
+typedef void (gl_APIENTRY *glExtGetRenderbuffersQCOM_client_proc_t) (void * ctx, GLuint*, GLint, GLint*);
+typedef void (gl_APIENTRY *glExtGetFramebuffersQCOM_client_proc_t) (void * ctx, GLuint*, GLint, GLint*);
+typedef void (gl_APIENTRY *glExtGetTexLevelParameterivQCOM_client_proc_t) (void * ctx, GLuint, GLenum, GLint, GLenum, GLint*);
+typedef void (gl_APIENTRY *glExtTexObjectStateOverrideiQCOM_client_proc_t) (void * ctx, GLenum, GLenum, GLint);
+typedef void (gl_APIENTRY *glExtGetTexSubImageQCOM_client_proc_t) (void * ctx, GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, GLvoid*);
+typedef void (gl_APIENTRY *glExtGetBufferPointervQCOM_client_proc_t) (void * ctx, GLenum, GLvoid**);
+typedef void (gl_APIENTRY *glExtGetShadersQCOM_client_proc_t) (void * ctx, GLuint*, GLint, GLint*);
+typedef void (gl_APIENTRY *glExtGetProgramsQCOM_client_proc_t) (void * ctx, GLuint*, GLint, GLint*);
+typedef GLboolean (gl_APIENTRY *glExtIsProgramBinaryQCOM_client_proc_t) (void * ctx, GLuint);
+typedef void (gl_APIENTRY *glExtGetProgramBinarySourceQCOM_client_proc_t) (void * ctx, GLuint, GLenum, GLchar*, GLint*);
+typedef void (gl_APIENTRY *glStartTilingQCOM_client_proc_t) (void * ctx, GLuint, GLuint, GLuint, GLuint, GLbitfield);
+typedef void (gl_APIENTRY *glEndTilingQCOM_client_proc_t) (void * ctx, GLbitfield);
+
+
+#endif
diff --git a/opengl/system/GLESv1_enc/gl_enc.cpp b/opengl/system/GLESv1_enc/gl_enc.cpp
new file mode 100644
index 0000000..0a343df
--- /dev/null
+++ b/opengl/system/GLESv1_enc/gl_enc.cpp
@@ -0,0 +1,5184 @@
+// Generated Code - DO NOT EDIT !!
+// generated by 'emugen'
+
+
+#include <string.h>
+#include "gl_opcodes.h"
+
+#include "gl_enc.h"
+
+
+#include <stdio.h>
+static void enc_unsupported()
+{
+	ALOGE("Function is unsupported\n");
+}
+
+void glAlphaFunc_enc(void *self , GLenum func, GLclampf ref)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glAlphaFunc;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &func, 4); ptr += 4;
+		memcpy(ptr, &ref, 4); ptr += 4;
+}
+
+void glClearColor_enc(void *self , GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glClearColor;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &red, 4); ptr += 4;
+		memcpy(ptr, &green, 4); ptr += 4;
+		memcpy(ptr, &blue, 4); ptr += 4;
+		memcpy(ptr, &alpha, 4); ptr += 4;
+}
+
+void glClearDepthf_enc(void *self , GLclampf depth)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glClearDepthf;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &depth, 4); ptr += 4;
+}
+
+void glClipPlanef_enc(void *self , GLenum plane, const GLfloat* equation)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_equation =  (4 * sizeof(float));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_equation + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glClipPlanef;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &plane, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_equation; ptr += 4;
+	memcpy(ptr, equation, __size_equation);ptr += __size_equation;
+}
+
+void glColor4f_enc(void *self , GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glColor4f;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &red, 4); ptr += 4;
+		memcpy(ptr, &green, 4); ptr += 4;
+		memcpy(ptr, &blue, 4); ptr += 4;
+		memcpy(ptr, &alpha, 4); ptr += 4;
+}
+
+void glDepthRangef_enc(void *self , GLclampf zNear, GLclampf zFar)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glDepthRangef;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &zNear, 4); ptr += 4;
+		memcpy(ptr, &zFar, 4); ptr += 4;
+}
+
+void glFogf_enc(void *self , GLenum pname, GLfloat param)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glFogf;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &pname, 4); ptr += 4;
+		memcpy(ptr, &param, 4); ptr += 4;
+}
+
+void glFogfv_enc(void *self , GLenum pname, const GLfloat* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLfloat));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glFogfv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	memcpy(ptr, params, __size_params);ptr += __size_params;
+}
+
+void glFrustumf_enc(void *self , GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glFrustumf;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &left, 4); ptr += 4;
+		memcpy(ptr, &right, 4); ptr += 4;
+		memcpy(ptr, &bottom, 4); ptr += 4;
+		memcpy(ptr, &top, 4); ptr += 4;
+		memcpy(ptr, &zNear, 4); ptr += 4;
+		memcpy(ptr, &zFar, 4); ptr += 4;
+}
+
+void glGetClipPlanef_enc(void *self , GLenum pname, GLfloat* eqn)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_eqn =  (4 * sizeof(GLfloat));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_eqn + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetClipPlanef;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_eqn; ptr += 4;
+	stream->readback(eqn, __size_eqn);
+}
+
+void glGetFloatv_enc(void *self , GLenum pname, GLfloat* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLfloat));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetFloatv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	stream->readback(params, __size_params);
+}
+
+void glGetLightfv_enc(void *self , GLenum light, GLenum pname, GLfloat* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLfloat));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetLightfv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &light, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	stream->readback(params, __size_params);
+}
+
+void glGetMaterialfv_enc(void *self , GLenum face, GLenum pname, GLfloat* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLfloat));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetMaterialfv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &face, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	stream->readback(params, __size_params);
+}
+
+void glGetTexEnvfv_enc(void *self , GLenum env, GLenum pname, GLfloat* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLfloat));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetTexEnvfv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &env, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	stream->readback(params, __size_params);
+}
+
+void glGetTexParameterfv_enc(void *self , GLenum target, GLenum pname, GLfloat* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLfloat));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetTexParameterfv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	stream->readback(params, __size_params);
+}
+
+void glLightModelf_enc(void *self , GLenum pname, GLfloat param)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glLightModelf;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &pname, 4); ptr += 4;
+		memcpy(ptr, &param, 4); ptr += 4;
+}
+
+void glLightModelfv_enc(void *self , GLenum pname, const GLfloat* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLfloat));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glLightModelfv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	memcpy(ptr, params, __size_params);ptr += __size_params;
+}
+
+void glLightf_enc(void *self , GLenum light, GLenum pname, GLfloat param)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glLightf;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &light, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+		memcpy(ptr, &param, 4); ptr += 4;
+}
+
+void glLightfv_enc(void *self , GLenum light, GLenum pname, const GLfloat* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLfloat));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glLightfv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &light, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	memcpy(ptr, params, __size_params);ptr += __size_params;
+}
+
+void glLineWidth_enc(void *self , GLfloat width)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glLineWidth;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &width, 4); ptr += 4;
+}
+
+void glLoadMatrixf_enc(void *self , const GLfloat* m)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_m =  (16 * sizeof(GLfloat));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + __size_m + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glLoadMatrixf;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+	*(unsigned int *)(ptr) = __size_m; ptr += 4;
+	memcpy(ptr, m, __size_m);ptr += __size_m;
+}
+
+void glMaterialf_enc(void *self , GLenum face, GLenum pname, GLfloat param)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glMaterialf;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &face, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+		memcpy(ptr, &param, 4); ptr += 4;
+}
+
+void glMaterialfv_enc(void *self , GLenum face, GLenum pname, const GLfloat* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLfloat));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glMaterialfv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &face, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	memcpy(ptr, params, __size_params);ptr += __size_params;
+}
+
+void glMultMatrixf_enc(void *self , const GLfloat* m)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_m =  (16 * sizeof(GLfloat));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + __size_m + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glMultMatrixf;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+	*(unsigned int *)(ptr) = __size_m; ptr += 4;
+	memcpy(ptr, m, __size_m);ptr += __size_m;
+}
+
+void glMultiTexCoord4f_enc(void *self , GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glMultiTexCoord4f;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &s, 4); ptr += 4;
+		memcpy(ptr, &t, 4); ptr += 4;
+		memcpy(ptr, &r, 4); ptr += 4;
+		memcpy(ptr, &q, 4); ptr += 4;
+}
+
+void glNormal3f_enc(void *self , GLfloat nx, GLfloat ny, GLfloat nz)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glNormal3f;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &nx, 4); ptr += 4;
+		memcpy(ptr, &ny, 4); ptr += 4;
+		memcpy(ptr, &nz, 4); ptr += 4;
+}
+
+void glOrthof_enc(void *self , GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glOrthof;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &left, 4); ptr += 4;
+		memcpy(ptr, &right, 4); ptr += 4;
+		memcpy(ptr, &bottom, 4); ptr += 4;
+		memcpy(ptr, &top, 4); ptr += 4;
+		memcpy(ptr, &zNear, 4); ptr += 4;
+		memcpy(ptr, &zFar, 4); ptr += 4;
+}
+
+void glPointParameterf_enc(void *self , GLenum pname, GLfloat param)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glPointParameterf;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &pname, 4); ptr += 4;
+		memcpy(ptr, &param, 4); ptr += 4;
+}
+
+void glPointParameterfv_enc(void *self , GLenum pname, const GLfloat* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLfloat));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glPointParameterfv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	memcpy(ptr, params, __size_params);ptr += __size_params;
+}
+
+void glPointSize_enc(void *self , GLfloat size)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glPointSize;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &size, 4); ptr += 4;
+}
+
+void glPolygonOffset_enc(void *self , GLfloat factor, GLfloat units)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glPolygonOffset;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &factor, 4); ptr += 4;
+		memcpy(ptr, &units, 4); ptr += 4;
+}
+
+void glRotatef_enc(void *self , GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glRotatef;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &angle, 4); ptr += 4;
+		memcpy(ptr, &x, 4); ptr += 4;
+		memcpy(ptr, &y, 4); ptr += 4;
+		memcpy(ptr, &z, 4); ptr += 4;
+}
+
+void glScalef_enc(void *self , GLfloat x, GLfloat y, GLfloat z)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glScalef;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &x, 4); ptr += 4;
+		memcpy(ptr, &y, 4); ptr += 4;
+		memcpy(ptr, &z, 4); ptr += 4;
+}
+
+void glTexEnvf_enc(void *self , GLenum target, GLenum pname, GLfloat param)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glTexEnvf;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+		memcpy(ptr, &param, 4); ptr += 4;
+}
+
+void glTexEnvfv_enc(void *self , GLenum target, GLenum pname, const GLfloat* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLfloat));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glTexEnvfv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	memcpy(ptr, params, __size_params);ptr += __size_params;
+}
+
+void glTexParameterf_enc(void *self , GLenum target, GLenum pname, GLfloat param)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glTexParameterf;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+		memcpy(ptr, &param, 4); ptr += 4;
+}
+
+void glTexParameterfv_enc(void *self , GLenum target, GLenum pname, const GLfloat* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLfloat));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glTexParameterfv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	memcpy(ptr, params, __size_params);ptr += __size_params;
+}
+
+void glTranslatef_enc(void *self , GLfloat x, GLfloat y, GLfloat z)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glTranslatef;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &x, 4); ptr += 4;
+		memcpy(ptr, &y, 4); ptr += 4;
+		memcpy(ptr, &z, 4); ptr += 4;
+}
+
+void glActiveTexture_enc(void *self , GLenum texture)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glActiveTexture;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &texture, 4); ptr += 4;
+}
+
+void glAlphaFuncx_enc(void *self , GLenum func, GLclampx ref)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glAlphaFuncx;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &func, 4); ptr += 4;
+		memcpy(ptr, &ref, 4); ptr += 4;
+}
+
+void glBindBuffer_enc(void *self , GLenum target, GLuint buffer)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glBindBuffer;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &buffer, 4); ptr += 4;
+}
+
+void glBindTexture_enc(void *self , GLenum target, GLuint texture)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glBindTexture;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &texture, 4); ptr += 4;
+}
+
+void glBlendFunc_enc(void *self , GLenum sfactor, GLenum dfactor)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glBlendFunc;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &sfactor, 4); ptr += 4;
+		memcpy(ptr, &dfactor, 4); ptr += 4;
+}
+
+void glBufferData_enc(void *self , GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_data =  size;
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_data + 4 + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glBufferData;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &size, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_data; ptr += 4;
+	memcpy(ptr, data, __size_data);ptr += __size_data;
+		memcpy(ptr, &usage, 4); ptr += 4;
+}
+
+void glBufferSubData_enc(void *self , GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_data =  size;
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + __size_data + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glBufferSubData;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &offset, 4); ptr += 4;
+		memcpy(ptr, &size, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_data; ptr += 4;
+	memcpy(ptr, data, __size_data);ptr += __size_data;
+}
+
+void glClear_enc(void *self , GLbitfield mask)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glClear;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &mask, 4); ptr += 4;
+}
+
+void glClearColorx_enc(void *self , GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glClearColorx;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &red, 4); ptr += 4;
+		memcpy(ptr, &green, 4); ptr += 4;
+		memcpy(ptr, &blue, 4); ptr += 4;
+		memcpy(ptr, &alpha, 4); ptr += 4;
+}
+
+void glClearDepthx_enc(void *self , GLclampx depth)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glClearDepthx;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &depth, 4); ptr += 4;
+}
+
+void glClearStencil_enc(void *self , GLint s)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glClearStencil;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &s, 4); ptr += 4;
+}
+
+void glClientActiveTexture_enc(void *self , GLenum texture)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glClientActiveTexture;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &texture, 4); ptr += 4;
+}
+
+void glColor4ub_enc(void *self , GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 1 + 1 + 1 + 1;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glColor4ub;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &red, 1); ptr += 1;
+		memcpy(ptr, &green, 1); ptr += 1;
+		memcpy(ptr, &blue, 1); ptr += 1;
+		memcpy(ptr, &alpha, 1); ptr += 1;
+}
+
+void glColor4x_enc(void *self , GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glColor4x;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &red, 4); ptr += 4;
+		memcpy(ptr, &green, 4); ptr += 4;
+		memcpy(ptr, &blue, 4); ptr += 4;
+		memcpy(ptr, &alpha, 4); ptr += 4;
+}
+
+void glColorMask_enc(void *self , GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 1 + 1 + 1 + 1;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glColorMask;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &red, 1); ptr += 1;
+		memcpy(ptr, &green, 1); ptr += 1;
+		memcpy(ptr, &blue, 1); ptr += 1;
+		memcpy(ptr, &alpha, 1); ptr += 1;
+}
+
+void glCompressedTexImage2D_enc(void *self , GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_data = ((data != NULL) ?  imageSize : 0);
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + __size_data + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glCompressedTexImage2D;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &level, 4); ptr += 4;
+		memcpy(ptr, &internalformat, 4); ptr += 4;
+		memcpy(ptr, &width, 4); ptr += 4;
+		memcpy(ptr, &height, 4); ptr += 4;
+		memcpy(ptr, &border, 4); ptr += 4;
+		memcpy(ptr, &imageSize, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_data; ptr += 4;
+	if (data != NULL) memcpy(ptr, data, __size_data);ptr += __size_data;
+}
+
+void glCompressedTexSubImage2D_enc(void *self , GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_data =  imageSize;
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + __size_data + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glCompressedTexSubImage2D;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &level, 4); ptr += 4;
+		memcpy(ptr, &xoffset, 4); ptr += 4;
+		memcpy(ptr, &yoffset, 4); ptr += 4;
+		memcpy(ptr, &width, 4); ptr += 4;
+		memcpy(ptr, &height, 4); ptr += 4;
+		memcpy(ptr, &format, 4); ptr += 4;
+		memcpy(ptr, &imageSize, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_data; ptr += 4;
+	memcpy(ptr, data, __size_data);ptr += __size_data;
+}
+
+void glCopyTexImage2D_enc(void *self , GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glCopyTexImage2D;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &level, 4); ptr += 4;
+		memcpy(ptr, &internalformat, 4); ptr += 4;
+		memcpy(ptr, &x, 4); ptr += 4;
+		memcpy(ptr, &y, 4); ptr += 4;
+		memcpy(ptr, &width, 4); ptr += 4;
+		memcpy(ptr, &height, 4); ptr += 4;
+		memcpy(ptr, &border, 4); ptr += 4;
+}
+
+void glCopyTexSubImage2D_enc(void *self , GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glCopyTexSubImage2D;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &level, 4); ptr += 4;
+		memcpy(ptr, &xoffset, 4); ptr += 4;
+		memcpy(ptr, &yoffset, 4); ptr += 4;
+		memcpy(ptr, &x, 4); ptr += 4;
+		memcpy(ptr, &y, 4); ptr += 4;
+		memcpy(ptr, &width, 4); ptr += 4;
+		memcpy(ptr, &height, 4); ptr += 4;
+}
+
+void glCullFace_enc(void *self , GLenum mode)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glCullFace;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &mode, 4); ptr += 4;
+}
+
+void glDeleteBuffers_enc(void *self , GLsizei n, const GLuint* buffers)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_buffers =  (n * sizeof(GLuint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_buffers + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glDeleteBuffers;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &n, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_buffers; ptr += 4;
+	memcpy(ptr, buffers, __size_buffers);ptr += __size_buffers;
+}
+
+void glDeleteTextures_enc(void *self , GLsizei n, const GLuint* textures)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_textures =  (n * sizeof(GLuint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_textures + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glDeleteTextures;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &n, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_textures; ptr += 4;
+	memcpy(ptr, textures, __size_textures);ptr += __size_textures;
+}
+
+void glDepthFunc_enc(void *self , GLenum func)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glDepthFunc;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &func, 4); ptr += 4;
+}
+
+void glDepthMask_enc(void *self , GLboolean flag)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 1;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glDepthMask;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &flag, 1); ptr += 1;
+}
+
+void glDepthRangex_enc(void *self , GLclampx zNear, GLclampx zFar)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glDepthRangex;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &zNear, 4); ptr += 4;
+		memcpy(ptr, &zFar, 4); ptr += 4;
+}
+
+void glDisable_enc(void *self , GLenum cap)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glDisable;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &cap, 4); ptr += 4;
+}
+
+void glDisableClientState_enc(void *self , GLenum array)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glDisableClientState;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &array, 4); ptr += 4;
+}
+
+void glDrawArrays_enc(void *self , GLenum mode, GLint first, GLsizei count)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glDrawArrays;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &mode, 4); ptr += 4;
+		memcpy(ptr, &first, 4); ptr += 4;
+		memcpy(ptr, &count, 4); ptr += 4;
+}
+
+void glEnable_enc(void *self , GLenum cap)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glEnable;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &cap, 4); ptr += 4;
+}
+
+void glEnableClientState_enc(void *self , GLenum array)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glEnableClientState;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &array, 4); ptr += 4;
+}
+
+void glFinish_enc(void *self )
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 0;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glFinish;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+}
+
+void glFlush_enc(void *self )
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 0;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glFlush;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+}
+
+void glFogx_enc(void *self , GLenum pname, GLfixed param)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glFogx;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &pname, 4); ptr += 4;
+		memcpy(ptr, &param, 4); ptr += 4;
+}
+
+void glFogxv_enc(void *self , GLenum pname, const GLfixed* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLfixed));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glFogxv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	memcpy(ptr, params, __size_params);ptr += __size_params;
+}
+
+void glFrontFace_enc(void *self , GLenum mode)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glFrontFace;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &mode, 4); ptr += 4;
+}
+
+void glFrustumx_enc(void *self , GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glFrustumx;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &left, 4); ptr += 4;
+		memcpy(ptr, &right, 4); ptr += 4;
+		memcpy(ptr, &bottom, 4); ptr += 4;
+		memcpy(ptr, &top, 4); ptr += 4;
+		memcpy(ptr, &zNear, 4); ptr += 4;
+		memcpy(ptr, &zFar, 4); ptr += 4;
+}
+
+void glGetBooleanv_enc(void *self , GLenum pname, GLboolean* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLboolean));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetBooleanv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	stream->readback(params, __size_params);
+}
+
+void glGetBufferParameteriv_enc(void *self , GLenum target, GLenum pname, GLint* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (sizeof(GLint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetBufferParameteriv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	stream->readback(params, __size_params);
+}
+
+void glClipPlanex_enc(void *self , GLenum pname, const GLfixed* eqn)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_eqn =  (4 * sizeof(GLfixed));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_eqn + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glClipPlanex;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_eqn; ptr += 4;
+	memcpy(ptr, eqn, __size_eqn);ptr += __size_eqn;
+}
+
+void glGenBuffers_enc(void *self , GLsizei n, GLuint* buffers)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_buffers =  (n * sizeof(GLuint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_buffers + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGenBuffers;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &n, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_buffers; ptr += 4;
+	stream->readback(buffers, __size_buffers);
+}
+
+void glGenTextures_enc(void *self , GLsizei n, GLuint* textures)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_textures =  (n * sizeof(GLuint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_textures + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGenTextures;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &n, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_textures; ptr += 4;
+	stream->readback(textures, __size_textures);
+}
+
+GLenum glGetError_enc(void *self )
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 0;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetError;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+
+	GLenum retval;
+	stream->readback(&retval, 4);
+	return retval;
+}
+
+void glGetFixedv_enc(void *self , GLenum pname, GLfixed* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLfixed));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetFixedv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	stream->readback(params, __size_params);
+}
+
+void glGetIntegerv_enc(void *self , GLenum pname, GLint* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetIntegerv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	stream->readback(params, __size_params);
+}
+
+void glGetLightxv_enc(void *self , GLenum light, GLenum pname, GLfixed* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLfixed));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetLightxv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &light, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	stream->readback(params, __size_params);
+}
+
+void glGetMaterialxv_enc(void *self , GLenum face, GLenum pname, GLfixed* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLfixed));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetMaterialxv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &face, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	stream->readback(params, __size_params);
+}
+
+void glGetTexEnviv_enc(void *self , GLenum env, GLenum pname, GLint* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetTexEnviv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &env, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	stream->readback(params, __size_params);
+}
+
+void glGetTexEnvxv_enc(void *self , GLenum env, GLenum pname, GLfixed* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLfixed));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetTexEnvxv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &env, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	stream->readback(params, __size_params);
+}
+
+void glGetTexParameteriv_enc(void *self , GLenum target, GLenum pname, GLint* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (sizeof(GLint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetTexParameteriv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	stream->readback(params, __size_params);
+}
+
+void glGetTexParameterxv_enc(void *self , GLenum target, GLenum pname, GLfixed* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (sizeof(GLfixed));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetTexParameterxv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	stream->readback(params, __size_params);
+}
+
+void glHint_enc(void *self , GLenum target, GLenum mode)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glHint;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &mode, 4); ptr += 4;
+}
+
+GLboolean glIsBuffer_enc(void *self , GLuint buffer)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glIsBuffer;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &buffer, 4); ptr += 4;
+
+	GLboolean retval;
+	stream->readback(&retval, 1);
+	return retval;
+}
+
+GLboolean glIsEnabled_enc(void *self , GLenum cap)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glIsEnabled;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &cap, 4); ptr += 4;
+
+	GLboolean retval;
+	stream->readback(&retval, 1);
+	return retval;
+}
+
+GLboolean glIsTexture_enc(void *self , GLuint texture)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glIsTexture;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &texture, 4); ptr += 4;
+
+	GLboolean retval;
+	stream->readback(&retval, 1);
+	return retval;
+}
+
+void glLightModelx_enc(void *self , GLenum pname, GLfixed param)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glLightModelx;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &pname, 4); ptr += 4;
+		memcpy(ptr, &param, 4); ptr += 4;
+}
+
+void glLightModelxv_enc(void *self , GLenum pname, const GLfixed* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLfixed));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glLightModelxv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	memcpy(ptr, params, __size_params);ptr += __size_params;
+}
+
+void glLightx_enc(void *self , GLenum light, GLenum pname, GLfixed param)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glLightx;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &light, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+		memcpy(ptr, &param, 4); ptr += 4;
+}
+
+void glLightxv_enc(void *self , GLenum light, GLenum pname, const GLfixed* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLfixed));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glLightxv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &light, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	memcpy(ptr, params, __size_params);ptr += __size_params;
+}
+
+void glLineWidthx_enc(void *self , GLfixed width)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glLineWidthx;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &width, 4); ptr += 4;
+}
+
+void glLoadIdentity_enc(void *self )
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 0;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glLoadIdentity;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+}
+
+void glLoadMatrixx_enc(void *self , const GLfixed* m)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_m =  (16 * sizeof(GLfixed));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + __size_m + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glLoadMatrixx;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+	*(unsigned int *)(ptr) = __size_m; ptr += 4;
+	memcpy(ptr, m, __size_m);ptr += __size_m;
+}
+
+void glLogicOp_enc(void *self , GLenum opcode)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glLogicOp;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &opcode, 4); ptr += 4;
+}
+
+void glMaterialx_enc(void *self , GLenum face, GLenum pname, GLfixed param)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glMaterialx;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &face, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+		memcpy(ptr, &param, 4); ptr += 4;
+}
+
+void glMaterialxv_enc(void *self , GLenum face, GLenum pname, const GLfixed* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLfixed));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glMaterialxv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &face, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	memcpy(ptr, params, __size_params);ptr += __size_params;
+}
+
+void glMatrixMode_enc(void *self , GLenum mode)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glMatrixMode;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &mode, 4); ptr += 4;
+}
+
+void glMultMatrixx_enc(void *self , const GLfixed* m)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_m =  (16 * sizeof(GLfixed));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + __size_m + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glMultMatrixx;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+	*(unsigned int *)(ptr) = __size_m; ptr += 4;
+	memcpy(ptr, m, __size_m);ptr += __size_m;
+}
+
+void glMultiTexCoord4x_enc(void *self , GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glMultiTexCoord4x;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &s, 4); ptr += 4;
+		memcpy(ptr, &t, 4); ptr += 4;
+		memcpy(ptr, &r, 4); ptr += 4;
+		memcpy(ptr, &q, 4); ptr += 4;
+}
+
+void glNormal3x_enc(void *self , GLfixed nx, GLfixed ny, GLfixed nz)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glNormal3x;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &nx, 4); ptr += 4;
+		memcpy(ptr, &ny, 4); ptr += 4;
+		memcpy(ptr, &nz, 4); ptr += 4;
+}
+
+void glOrthox_enc(void *self , GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glOrthox;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &left, 4); ptr += 4;
+		memcpy(ptr, &right, 4); ptr += 4;
+		memcpy(ptr, &bottom, 4); ptr += 4;
+		memcpy(ptr, &top, 4); ptr += 4;
+		memcpy(ptr, &zNear, 4); ptr += 4;
+		memcpy(ptr, &zFar, 4); ptr += 4;
+}
+
+void glPixelStorei_enc(void *self , GLenum pname, GLint param)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glPixelStorei;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &pname, 4); ptr += 4;
+		memcpy(ptr, &param, 4); ptr += 4;
+}
+
+void glPointParameterx_enc(void *self , GLenum pname, GLfixed param)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glPointParameterx;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &pname, 4); ptr += 4;
+		memcpy(ptr, &param, 4); ptr += 4;
+}
+
+void glPointParameterxv_enc(void *self , GLenum pname, const GLfixed* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLfixed));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glPointParameterxv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	memcpy(ptr, params, __size_params);ptr += __size_params;
+}
+
+void glPointSizex_enc(void *self , GLfixed size)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glPointSizex;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &size, 4); ptr += 4;
+}
+
+void glPolygonOffsetx_enc(void *self , GLfixed factor, GLfixed units)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glPolygonOffsetx;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &factor, 4); ptr += 4;
+		memcpy(ptr, &units, 4); ptr += 4;
+}
+
+void glPopMatrix_enc(void *self )
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 0;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glPopMatrix;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+}
+
+void glPushMatrix_enc(void *self )
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 0;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glPushMatrix;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+}
+
+void glReadPixels_enc(void *self , GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_pixels =  pixelDataSize(self, width, height, format, type, 1);
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4 + 4 + __size_pixels + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glReadPixels;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &x, 4); ptr += 4;
+		memcpy(ptr, &y, 4); ptr += 4;
+		memcpy(ptr, &width, 4); ptr += 4;
+		memcpy(ptr, &height, 4); ptr += 4;
+		memcpy(ptr, &format, 4); ptr += 4;
+		memcpy(ptr, &type, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_pixels; ptr += 4;
+	stream->readback(pixels, __size_pixels);
+}
+
+void glRotatex_enc(void *self , GLfixed angle, GLfixed x, GLfixed y, GLfixed z)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glRotatex;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &angle, 4); ptr += 4;
+		memcpy(ptr, &x, 4); ptr += 4;
+		memcpy(ptr, &y, 4); ptr += 4;
+		memcpy(ptr, &z, 4); ptr += 4;
+}
+
+void glSampleCoverage_enc(void *self , GLclampf value, GLboolean invert)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 1;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glSampleCoverage;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &value, 4); ptr += 4;
+		memcpy(ptr, &invert, 1); ptr += 1;
+}
+
+void glSampleCoveragex_enc(void *self , GLclampx value, GLboolean invert)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 1;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glSampleCoveragex;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &value, 4); ptr += 4;
+		memcpy(ptr, &invert, 1); ptr += 1;
+}
+
+void glScalex_enc(void *self , GLfixed x, GLfixed y, GLfixed z)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glScalex;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &x, 4); ptr += 4;
+		memcpy(ptr, &y, 4); ptr += 4;
+		memcpy(ptr, &z, 4); ptr += 4;
+}
+
+void glScissor_enc(void *self , GLint x, GLint y, GLsizei width, GLsizei height)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glScissor;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &x, 4); ptr += 4;
+		memcpy(ptr, &y, 4); ptr += 4;
+		memcpy(ptr, &width, 4); ptr += 4;
+		memcpy(ptr, &height, 4); ptr += 4;
+}
+
+void glShadeModel_enc(void *self , GLenum mode)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glShadeModel;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &mode, 4); ptr += 4;
+}
+
+void glStencilFunc_enc(void *self , GLenum func, GLint ref, GLuint mask)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glStencilFunc;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &func, 4); ptr += 4;
+		memcpy(ptr, &ref, 4); ptr += 4;
+		memcpy(ptr, &mask, 4); ptr += 4;
+}
+
+void glStencilMask_enc(void *self , GLuint mask)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glStencilMask;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &mask, 4); ptr += 4;
+}
+
+void glStencilOp_enc(void *self , GLenum fail, GLenum zfail, GLenum zpass)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glStencilOp;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &fail, 4); ptr += 4;
+		memcpy(ptr, &zfail, 4); ptr += 4;
+		memcpy(ptr, &zpass, 4); ptr += 4;
+}
+
+void glTexEnvi_enc(void *self , GLenum target, GLenum pname, GLint param)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glTexEnvi;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+		memcpy(ptr, &param, 4); ptr += 4;
+}
+
+void glTexEnvx_enc(void *self , GLenum target, GLenum pname, GLfixed param)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glTexEnvx;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+		memcpy(ptr, &param, 4); ptr += 4;
+}
+
+void glTexEnviv_enc(void *self , GLenum target, GLenum pname, const GLint* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glTexEnviv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	memcpy(ptr, params, __size_params);ptr += __size_params;
+}
+
+void glTexEnvxv_enc(void *self , GLenum target, GLenum pname, const GLfixed* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLfixed));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glTexEnvxv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	memcpy(ptr, params, __size_params);ptr += __size_params;
+}
+
+void glTexImage2D_enc(void *self , GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_pixels = ((pixels != NULL) ?  pixelDataSize(self, width, height, format, type, 0) : 0);
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + __size_pixels + 1*4;
+	ptr = stream->alloc(8 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4);
+	int tmp = OP_glTexImage2D;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &level, 4); ptr += 4;
+		memcpy(ptr, &internalformat, 4); ptr += 4;
+		memcpy(ptr, &width, 4); ptr += 4;
+		memcpy(ptr, &height, 4); ptr += 4;
+		memcpy(ptr, &border, 4); ptr += 4;
+		memcpy(ptr, &format, 4); ptr += 4;
+		memcpy(ptr, &type, 4); ptr += 4;
+	stream->flush();
+	stream->writeFully(&__size_pixels,4);
+	if (pixels != NULL) stream->writeFully(pixels, __size_pixels);
+}
+
+void glTexParameteri_enc(void *self , GLenum target, GLenum pname, GLint param)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glTexParameteri;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+		memcpy(ptr, &param, 4); ptr += 4;
+}
+
+void glTexParameterx_enc(void *self , GLenum target, GLenum pname, GLfixed param)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glTexParameterx;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+		memcpy(ptr, &param, 4); ptr += 4;
+}
+
+void glTexParameteriv_enc(void *self , GLenum target, GLenum pname, const GLint* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glTexParameteriv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	memcpy(ptr, params, __size_params);ptr += __size_params;
+}
+
+void glTexParameterxv_enc(void *self , GLenum target, GLenum pname, const GLfixed* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLfixed));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glTexParameterxv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	memcpy(ptr, params, __size_params);ptr += __size_params;
+}
+
+void glTexSubImage2D_enc(void *self , GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_pixels =  pixelDataSize(self, width, height, format, type, 0);
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + __size_pixels + 1*4;
+	ptr = stream->alloc(8 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4);
+	int tmp = OP_glTexSubImage2D;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &level, 4); ptr += 4;
+		memcpy(ptr, &xoffset, 4); ptr += 4;
+		memcpy(ptr, &yoffset, 4); ptr += 4;
+		memcpy(ptr, &width, 4); ptr += 4;
+		memcpy(ptr, &height, 4); ptr += 4;
+		memcpy(ptr, &format, 4); ptr += 4;
+		memcpy(ptr, &type, 4); ptr += 4;
+	stream->flush();
+	stream->writeFully(&__size_pixels,4);
+	stream->writeFully(pixels, __size_pixels);
+}
+
+void glTranslatex_enc(void *self , GLfixed x, GLfixed y, GLfixed z)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glTranslatex;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &x, 4); ptr += 4;
+		memcpy(ptr, &y, 4); ptr += 4;
+		memcpy(ptr, &z, 4); ptr += 4;
+}
+
+void glViewport_enc(void *self , GLint x, GLint y, GLsizei width, GLsizei height)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glViewport;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &x, 4); ptr += 4;
+		memcpy(ptr, &y, 4); ptr += 4;
+		memcpy(ptr, &width, 4); ptr += 4;
+		memcpy(ptr, &height, 4); ptr += 4;
+}
+
+void glVertexPointerOffset_enc(void *self , GLint size, GLenum type, GLsizei stride, GLuint offset)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glVertexPointerOffset;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &size, 4); ptr += 4;
+		memcpy(ptr, &type, 4); ptr += 4;
+		memcpy(ptr, &stride, 4); ptr += 4;
+		memcpy(ptr, &offset, 4); ptr += 4;
+}
+
+void glColorPointerOffset_enc(void *self , GLint size, GLenum type, GLsizei stride, GLuint offset)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glColorPointerOffset;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &size, 4); ptr += 4;
+		memcpy(ptr, &type, 4); ptr += 4;
+		memcpy(ptr, &stride, 4); ptr += 4;
+		memcpy(ptr, &offset, 4); ptr += 4;
+}
+
+void glNormalPointerOffset_enc(void *self , GLenum type, GLsizei stride, GLuint offset)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glNormalPointerOffset;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &type, 4); ptr += 4;
+		memcpy(ptr, &stride, 4); ptr += 4;
+		memcpy(ptr, &offset, 4); ptr += 4;
+}
+
+void glPointSizePointerOffset_enc(void *self , GLenum type, GLsizei stride, GLuint offset)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glPointSizePointerOffset;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &type, 4); ptr += 4;
+		memcpy(ptr, &stride, 4); ptr += 4;
+		memcpy(ptr, &offset, 4); ptr += 4;
+}
+
+void glTexCoordPointerOffset_enc(void *self , GLint size, GLenum type, GLsizei stride, GLuint offset)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glTexCoordPointerOffset;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &size, 4); ptr += 4;
+		memcpy(ptr, &type, 4); ptr += 4;
+		memcpy(ptr, &stride, 4); ptr += 4;
+		memcpy(ptr, &offset, 4); ptr += 4;
+}
+
+void glWeightPointerOffset_enc(void *self , GLint size, GLenum type, GLsizei stride, GLuint offset)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glWeightPointerOffset;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &size, 4); ptr += 4;
+		memcpy(ptr, &type, 4); ptr += 4;
+		memcpy(ptr, &stride, 4); ptr += 4;
+		memcpy(ptr, &offset, 4); ptr += 4;
+}
+
+void glMatrixIndexPointerOffset_enc(void *self , GLint size, GLenum type, GLsizei stride, GLuint offset)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glMatrixIndexPointerOffset;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &size, 4); ptr += 4;
+		memcpy(ptr, &type, 4); ptr += 4;
+		memcpy(ptr, &stride, 4); ptr += 4;
+		memcpy(ptr, &offset, 4); ptr += 4;
+}
+
+void glVertexPointerData_enc(void *self , GLint size, GLenum type, GLsizei stride, void* data, GLuint datalen)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_data =  datalen;
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + __size_data + 4 + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glVertexPointerData;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &size, 4); ptr += 4;
+		memcpy(ptr, &type, 4); ptr += 4;
+		memcpy(ptr, &stride, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_data; ptr += 4;
+	 glUtilsPackPointerData((unsigned char *)ptr, (unsigned char *)data, size, type, stride, datalen);ptr += __size_data;
+		memcpy(ptr, &datalen, 4); ptr += 4;
+}
+
+void glColorPointerData_enc(void *self , GLint size, GLenum type, GLsizei stride, void* data, GLuint datalen)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_data =  datalen;
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + __size_data + 4 + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glColorPointerData;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &size, 4); ptr += 4;
+		memcpy(ptr, &type, 4); ptr += 4;
+		memcpy(ptr, &stride, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_data; ptr += 4;
+	 glUtilsPackPointerData((unsigned char *)ptr, (unsigned char *)data, size, type, stride, datalen);ptr += __size_data;
+		memcpy(ptr, &datalen, 4); ptr += 4;
+}
+
+void glNormalPointerData_enc(void *self , GLenum type, GLsizei stride, void* data, GLuint datalen)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_data =  datalen;
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_data + 4 + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glNormalPointerData;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &type, 4); ptr += 4;
+		memcpy(ptr, &stride, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_data; ptr += 4;
+	 glUtilsPackPointerData((unsigned char *)ptr, (unsigned char *)data, 3, type, stride, datalen);ptr += __size_data;
+		memcpy(ptr, &datalen, 4); ptr += 4;
+}
+
+void glTexCoordPointerData_enc(void *self , GLint unit, GLint size, GLenum type, GLsizei stride, void* data, GLuint datalen)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_data =  datalen;
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + __size_data + 4 + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glTexCoordPointerData;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &unit, 4); ptr += 4;
+		memcpy(ptr, &size, 4); ptr += 4;
+		memcpy(ptr, &type, 4); ptr += 4;
+		memcpy(ptr, &stride, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_data; ptr += 4;
+	 glUtilsPackPointerData((unsigned char *)ptr, (unsigned char *)data, size, type, stride, datalen);ptr += __size_data;
+		memcpy(ptr, &datalen, 4); ptr += 4;
+}
+
+void glPointSizePointerData_enc(void *self , GLenum type, GLsizei stride, void* data, GLuint datalen)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_data =  datalen;
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_data + 4 + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glPointSizePointerData;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &type, 4); ptr += 4;
+		memcpy(ptr, &stride, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_data; ptr += 4;
+	 glUtilsPackPointerData((unsigned char *)ptr, (unsigned char *)data, 1, type, stride, datalen);ptr += __size_data;
+		memcpy(ptr, &datalen, 4); ptr += 4;
+}
+
+void glWeightPointerData_enc(void *self , GLint size, GLenum type, GLsizei stride, void* data, GLuint datalen)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_data =  datalen;
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + __size_data + 4 + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glWeightPointerData;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &size, 4); ptr += 4;
+		memcpy(ptr, &type, 4); ptr += 4;
+		memcpy(ptr, &stride, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_data; ptr += 4;
+	 glUtilsPackPointerData((unsigned char *)ptr, (unsigned char*)data, size, type, stride, datalen);ptr += __size_data;
+		memcpy(ptr, &datalen, 4); ptr += 4;
+}
+
+void glMatrixIndexPointerData_enc(void *self , GLint size, GLenum type, GLsizei stride, void* data, GLuint datalen)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_data =  datalen;
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + __size_data + 4 + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glMatrixIndexPointerData;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &size, 4); ptr += 4;
+		memcpy(ptr, &type, 4); ptr += 4;
+		memcpy(ptr, &stride, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_data; ptr += 4;
+	 glUtilsPackPointerData((unsigned char *)ptr, (unsigned char*)data, size, type, stride, datalen);ptr += __size_data;
+		memcpy(ptr, &datalen, 4); ptr += 4;
+}
+
+void glDrawElementsOffset_enc(void *self , GLenum mode, GLsizei count, GLenum type, GLuint offset)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glDrawElementsOffset;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &mode, 4); ptr += 4;
+		memcpy(ptr, &count, 4); ptr += 4;
+		memcpy(ptr, &type, 4); ptr += 4;
+		memcpy(ptr, &offset, 4); ptr += 4;
+}
+
+void glDrawElementsData_enc(void *self , GLenum mode, GLsizei count, GLenum type, void* data, GLuint datalen)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_data =  datalen;
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + __size_data + 4 + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glDrawElementsData;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &mode, 4); ptr += 4;
+		memcpy(ptr, &count, 4); ptr += 4;
+		memcpy(ptr, &type, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_data; ptr += 4;
+	memcpy(ptr, data, __size_data);ptr += __size_data;
+		memcpy(ptr, &datalen, 4); ptr += 4;
+}
+
+void glGetCompressedTextureFormats_enc(void *self , int count, GLint* formats)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_formats =  (count * sizeof(GLint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_formats + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetCompressedTextureFormats;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &count, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_formats; ptr += 4;
+	stream->readback(formats, __size_formats);
+}
+
+int glFinishRoundTrip_enc(void *self )
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 0;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glFinishRoundTrip;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+
+	int retval;
+	stream->readback(&retval, 4);
+	return retval;
+}
+
+void glBlendEquationSeparateOES_enc(void *self , GLenum modeRGB, GLenum modeAlpha)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glBlendEquationSeparateOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &modeRGB, 4); ptr += 4;
+		memcpy(ptr, &modeAlpha, 4); ptr += 4;
+}
+
+void glBlendFuncSeparateOES_enc(void *self , GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glBlendFuncSeparateOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &srcRGB, 4); ptr += 4;
+		memcpy(ptr, &dstRGB, 4); ptr += 4;
+		memcpy(ptr, &srcAlpha, 4); ptr += 4;
+		memcpy(ptr, &dstAlpha, 4); ptr += 4;
+}
+
+void glBlendEquationOES_enc(void *self , GLenum mode)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glBlendEquationOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &mode, 4); ptr += 4;
+}
+
+void glDrawTexsOES_enc(void *self , GLshort x, GLshort y, GLshort z, GLshort width, GLshort height)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 2 + 2 + 2 + 2 + 2;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glDrawTexsOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &x, 2); ptr += 2;
+		memcpy(ptr, &y, 2); ptr += 2;
+		memcpy(ptr, &z, 2); ptr += 2;
+		memcpy(ptr, &width, 2); ptr += 2;
+		memcpy(ptr, &height, 2); ptr += 2;
+}
+
+void glDrawTexiOES_enc(void *self , GLint x, GLint y, GLint z, GLint width, GLint height)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glDrawTexiOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &x, 4); ptr += 4;
+		memcpy(ptr, &y, 4); ptr += 4;
+		memcpy(ptr, &z, 4); ptr += 4;
+		memcpy(ptr, &width, 4); ptr += 4;
+		memcpy(ptr, &height, 4); ptr += 4;
+}
+
+void glDrawTexxOES_enc(void *self , GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glDrawTexxOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &x, 4); ptr += 4;
+		memcpy(ptr, &y, 4); ptr += 4;
+		memcpy(ptr, &z, 4); ptr += 4;
+		memcpy(ptr, &width, 4); ptr += 4;
+		memcpy(ptr, &height, 4); ptr += 4;
+}
+
+void glDrawTexsvOES_enc(void *self , const GLshort* coords)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_coords =  (5 * sizeof(GLshort));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + __size_coords + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glDrawTexsvOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+	*(unsigned int *)(ptr) = __size_coords; ptr += 4;
+	memcpy(ptr, coords, __size_coords);ptr += __size_coords;
+}
+
+void glDrawTexivOES_enc(void *self , const GLint* coords)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_coords =  (5 * sizeof(GLint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + __size_coords + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glDrawTexivOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+	*(unsigned int *)(ptr) = __size_coords; ptr += 4;
+	memcpy(ptr, coords, __size_coords);ptr += __size_coords;
+}
+
+void glDrawTexxvOES_enc(void *self , const GLfixed* coords)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_coords =  (5 * sizeof(GLfixed));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + __size_coords + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glDrawTexxvOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+	*(unsigned int *)(ptr) = __size_coords; ptr += 4;
+	memcpy(ptr, coords, __size_coords);ptr += __size_coords;
+}
+
+void glDrawTexfOES_enc(void *self , GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glDrawTexfOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &x, 4); ptr += 4;
+		memcpy(ptr, &y, 4); ptr += 4;
+		memcpy(ptr, &z, 4); ptr += 4;
+		memcpy(ptr, &width, 4); ptr += 4;
+		memcpy(ptr, &height, 4); ptr += 4;
+}
+
+void glDrawTexfvOES_enc(void *self , const GLfloat* coords)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_coords =  (5 * sizeof(GLfloat));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + __size_coords + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glDrawTexfvOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+	*(unsigned int *)(ptr) = __size_coords; ptr += 4;
+	memcpy(ptr, coords, __size_coords);ptr += __size_coords;
+}
+
+void glEGLImageTargetTexture2DOES_enc(void *self , GLenum target, GLeglImageOES image)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glEGLImageTargetTexture2DOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &image, 4); ptr += 4;
+}
+
+void glEGLImageTargetRenderbufferStorageOES_enc(void *self , GLenum target, GLeglImageOES image)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glEGLImageTargetRenderbufferStorageOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &image, 4); ptr += 4;
+}
+
+void glAlphaFuncxOES_enc(void *self , GLenum func, GLclampx ref)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glAlphaFuncxOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &func, 4); ptr += 4;
+		memcpy(ptr, &ref, 4); ptr += 4;
+}
+
+void glClearColorxOES_enc(void *self , GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glClearColorxOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &red, 4); ptr += 4;
+		memcpy(ptr, &green, 4); ptr += 4;
+		memcpy(ptr, &blue, 4); ptr += 4;
+		memcpy(ptr, &alpha, 4); ptr += 4;
+}
+
+void glClearDepthxOES_enc(void *self , GLclampx depth)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glClearDepthxOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &depth, 4); ptr += 4;
+}
+
+void glClipPlanexOES_enc(void *self , GLenum plane, const GLfixed* equation)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_equation =  (4 * sizeof(GLfixed));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_equation + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glClipPlanexOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &plane, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_equation; ptr += 4;
+	memcpy(ptr, equation, __size_equation);ptr += __size_equation;
+}
+
+void glClipPlanexIMG_enc(void *self , GLenum plane, const GLfixed* equation)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_equation =  (4 * sizeof(GLfixed));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_equation + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glClipPlanexIMG;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &plane, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_equation; ptr += 4;
+	memcpy(ptr, equation, __size_equation);ptr += __size_equation;
+}
+
+void glColor4xOES_enc(void *self , GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glColor4xOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &red, 4); ptr += 4;
+		memcpy(ptr, &green, 4); ptr += 4;
+		memcpy(ptr, &blue, 4); ptr += 4;
+		memcpy(ptr, &alpha, 4); ptr += 4;
+}
+
+void glDepthRangexOES_enc(void *self , GLclampx zNear, GLclampx zFar)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glDepthRangexOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &zNear, 4); ptr += 4;
+		memcpy(ptr, &zFar, 4); ptr += 4;
+}
+
+void glFogxOES_enc(void *self , GLenum pname, GLfixed param)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glFogxOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &pname, 4); ptr += 4;
+		memcpy(ptr, &param, 4); ptr += 4;
+}
+
+void glFogxvOES_enc(void *self , GLenum pname, const GLfixed* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLfixed));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glFogxvOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	memcpy(ptr, params, __size_params);ptr += __size_params;
+}
+
+void glFrustumxOES_enc(void *self , GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glFrustumxOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &left, 4); ptr += 4;
+		memcpy(ptr, &right, 4); ptr += 4;
+		memcpy(ptr, &bottom, 4); ptr += 4;
+		memcpy(ptr, &top, 4); ptr += 4;
+		memcpy(ptr, &zNear, 4); ptr += 4;
+		memcpy(ptr, &zFar, 4); ptr += 4;
+}
+
+void glGetClipPlanexOES_enc(void *self , GLenum pname, GLfixed* eqn)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_eqn =  (4 * sizeof(GLfixed));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_eqn + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetClipPlanexOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_eqn; ptr += 4;
+	stream->readback(eqn, __size_eqn);
+}
+
+void glGetClipPlanex_enc(void *self , GLenum pname, GLfixed* eqn)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_eqn =  (4 * sizeof(GLfixed));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_eqn + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetClipPlanex;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_eqn; ptr += 4;
+	stream->readback(eqn, __size_eqn);
+}
+
+void glGetFixedvOES_enc(void *self , GLenum pname, GLfixed* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLfixed));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetFixedvOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	stream->readback(params, __size_params);
+}
+
+void glGetLightxvOES_enc(void *self , GLenum light, GLenum pname, GLfixed* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLfixed));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetLightxvOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &light, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	stream->readback(params, __size_params);
+}
+
+void glGetMaterialxvOES_enc(void *self , GLenum face, GLenum pname, GLfixed* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLfixed));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetMaterialxvOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &face, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	stream->readback(params, __size_params);
+}
+
+void glGetTexEnvxvOES_enc(void *self , GLenum env, GLenum pname, GLfixed* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLfixed));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetTexEnvxvOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &env, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	stream->readback(params, __size_params);
+}
+
+void glGetTexParameterxvOES_enc(void *self , GLenum target, GLenum pname, GLfixed* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLfixed));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetTexParameterxvOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	stream->readback(params, __size_params);
+}
+
+void glLightModelxOES_enc(void *self , GLenum pname, GLfixed param)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glLightModelxOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &pname, 4); ptr += 4;
+		memcpy(ptr, &param, 4); ptr += 4;
+}
+
+void glLightModelxvOES_enc(void *self , GLenum pname, const GLfixed* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLfixed));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glLightModelxvOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	memcpy(ptr, params, __size_params);ptr += __size_params;
+}
+
+void glLightxOES_enc(void *self , GLenum light, GLenum pname, GLfixed param)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glLightxOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &light, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+		memcpy(ptr, &param, 4); ptr += 4;
+}
+
+void glLightxvOES_enc(void *self , GLenum light, GLenum pname, const GLfixed* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLfixed));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glLightxvOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &light, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	memcpy(ptr, params, __size_params);ptr += __size_params;
+}
+
+void glLineWidthxOES_enc(void *self , GLfixed width)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glLineWidthxOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &width, 4); ptr += 4;
+}
+
+void glLoadMatrixxOES_enc(void *self , const GLfixed* m)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_m =  (16 * sizeof(GLfixed));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + __size_m + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glLoadMatrixxOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+	*(unsigned int *)(ptr) = __size_m; ptr += 4;
+	memcpy(ptr, m, __size_m);ptr += __size_m;
+}
+
+void glMaterialxOES_enc(void *self , GLenum face, GLenum pname, GLfixed param)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glMaterialxOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &face, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+		memcpy(ptr, &param, 4); ptr += 4;
+}
+
+void glMaterialxvOES_enc(void *self , GLenum face, GLenum pname, const GLfixed* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLfixed));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glMaterialxvOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &face, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	memcpy(ptr, params, __size_params);ptr += __size_params;
+}
+
+void glMultMatrixxOES_enc(void *self , const GLfixed* m)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_m =  (16 * sizeof(GLfixed));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + __size_m + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glMultMatrixxOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+	*(unsigned int *)(ptr) = __size_m; ptr += 4;
+	memcpy(ptr, m, __size_m);ptr += __size_m;
+}
+
+void glMultiTexCoord4xOES_enc(void *self , GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glMultiTexCoord4xOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &s, 4); ptr += 4;
+		memcpy(ptr, &t, 4); ptr += 4;
+		memcpy(ptr, &r, 4); ptr += 4;
+		memcpy(ptr, &q, 4); ptr += 4;
+}
+
+void glNormal3xOES_enc(void *self , GLfixed nx, GLfixed ny, GLfixed nz)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glNormal3xOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &nx, 4); ptr += 4;
+		memcpy(ptr, &ny, 4); ptr += 4;
+		memcpy(ptr, &nz, 4); ptr += 4;
+}
+
+void glOrthoxOES_enc(void *self , GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glOrthoxOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &left, 4); ptr += 4;
+		memcpy(ptr, &right, 4); ptr += 4;
+		memcpy(ptr, &bottom, 4); ptr += 4;
+		memcpy(ptr, &top, 4); ptr += 4;
+		memcpy(ptr, &zNear, 4); ptr += 4;
+		memcpy(ptr, &zFar, 4); ptr += 4;
+}
+
+void glPointParameterxOES_enc(void *self , GLenum pname, GLfixed param)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glPointParameterxOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &pname, 4); ptr += 4;
+		memcpy(ptr, &param, 4); ptr += 4;
+}
+
+void glPointParameterxvOES_enc(void *self , GLenum pname, const GLfixed* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLfixed));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glPointParameterxvOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	memcpy(ptr, params, __size_params);ptr += __size_params;
+}
+
+void glPointSizexOES_enc(void *self , GLfixed size)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glPointSizexOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &size, 4); ptr += 4;
+}
+
+void glPolygonOffsetxOES_enc(void *self , GLfixed factor, GLfixed units)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glPolygonOffsetxOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &factor, 4); ptr += 4;
+		memcpy(ptr, &units, 4); ptr += 4;
+}
+
+void glRotatexOES_enc(void *self , GLfixed angle, GLfixed x, GLfixed y, GLfixed z)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glRotatexOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &angle, 4); ptr += 4;
+		memcpy(ptr, &x, 4); ptr += 4;
+		memcpy(ptr, &y, 4); ptr += 4;
+		memcpy(ptr, &z, 4); ptr += 4;
+}
+
+void glSampleCoveragexOES_enc(void *self , GLclampx value, GLboolean invert)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 1;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glSampleCoveragexOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &value, 4); ptr += 4;
+		memcpy(ptr, &invert, 1); ptr += 1;
+}
+
+void glScalexOES_enc(void *self , GLfixed x, GLfixed y, GLfixed z)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glScalexOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &x, 4); ptr += 4;
+		memcpy(ptr, &y, 4); ptr += 4;
+		memcpy(ptr, &z, 4); ptr += 4;
+}
+
+void glTexEnvxOES_enc(void *self , GLenum target, GLenum pname, GLfixed param)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glTexEnvxOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+		memcpy(ptr, &param, 4); ptr += 4;
+}
+
+void glTexEnvxvOES_enc(void *self , GLenum target, GLenum pname, const GLfixed* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLfixed));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glTexEnvxvOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	memcpy(ptr, params, __size_params);ptr += __size_params;
+}
+
+void glTexParameterxOES_enc(void *self , GLenum target, GLenum pname, GLfixed param)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glTexParameterxOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+		memcpy(ptr, &param, 4); ptr += 4;
+}
+
+void glTexParameterxvOES_enc(void *self , GLenum target, GLenum pname, const GLfixed* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLfixed));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glTexParameterxvOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	memcpy(ptr, params, __size_params);ptr += __size_params;
+}
+
+void glTranslatexOES_enc(void *self , GLfixed x, GLfixed y, GLfixed z)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glTranslatexOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &x, 4); ptr += 4;
+		memcpy(ptr, &y, 4); ptr += 4;
+		memcpy(ptr, &z, 4); ptr += 4;
+}
+
+GLboolean glIsRenderbufferOES_enc(void *self , GLuint renderbuffer)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glIsRenderbufferOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &renderbuffer, 4); ptr += 4;
+
+	GLboolean retval;
+	stream->readback(&retval, 1);
+	return retval;
+}
+
+void glBindRenderbufferOES_enc(void *self , GLenum target, GLuint renderbuffer)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glBindRenderbufferOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &renderbuffer, 4); ptr += 4;
+}
+
+void glDeleteRenderbuffersOES_enc(void *self , GLsizei n, const GLuint* renderbuffers)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_renderbuffers =  (n * sizeof(GLuint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_renderbuffers + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glDeleteRenderbuffersOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &n, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_renderbuffers; ptr += 4;
+	memcpy(ptr, renderbuffers, __size_renderbuffers);ptr += __size_renderbuffers;
+}
+
+void glGenRenderbuffersOES_enc(void *self , GLsizei n, GLuint* renderbuffers)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_renderbuffers =  (n * sizeof(GLuint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_renderbuffers + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGenRenderbuffersOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &n, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_renderbuffers; ptr += 4;
+	stream->readback(renderbuffers, __size_renderbuffers);
+}
+
+void glRenderbufferStorageOES_enc(void *self , GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glRenderbufferStorageOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &internalformat, 4); ptr += 4;
+		memcpy(ptr, &width, 4); ptr += 4;
+		memcpy(ptr, &height, 4); ptr += 4;
+}
+
+void glGetRenderbufferParameterivOES_enc(void *self , GLenum target, GLenum pname, GLint* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetRenderbufferParameterivOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	stream->readback(params, __size_params);
+}
+
+GLboolean glIsFramebufferOES_enc(void *self , GLuint framebuffer)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glIsFramebufferOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &framebuffer, 4); ptr += 4;
+
+	GLboolean retval;
+	stream->readback(&retval, 1);
+	return retval;
+}
+
+void glBindFramebufferOES_enc(void *self , GLenum target, GLuint framebuffer)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glBindFramebufferOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &framebuffer, 4); ptr += 4;
+}
+
+void glDeleteFramebuffersOES_enc(void *self , GLsizei n, const GLuint* framebuffers)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_framebuffers =  (n * sizeof(GLuint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_framebuffers + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glDeleteFramebuffersOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &n, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_framebuffers; ptr += 4;
+	memcpy(ptr, framebuffers, __size_framebuffers);ptr += __size_framebuffers;
+}
+
+void glGenFramebuffersOES_enc(void *self , GLsizei n, GLuint* framebuffers)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_framebuffers =  (n * sizeof(GLuint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_framebuffers + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGenFramebuffersOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &n, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_framebuffers; ptr += 4;
+	stream->readback(framebuffers, __size_framebuffers);
+}
+
+GLenum glCheckFramebufferStatusOES_enc(void *self , GLenum target)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glCheckFramebufferStatusOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+
+	GLenum retval;
+	stream->readback(&retval, 4);
+	return retval;
+}
+
+void glFramebufferRenderbufferOES_enc(void *self , GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glFramebufferRenderbufferOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &attachment, 4); ptr += 4;
+		memcpy(ptr, &renderbuffertarget, 4); ptr += 4;
+		memcpy(ptr, &renderbuffer, 4); ptr += 4;
+}
+
+void glFramebufferTexture2DOES_enc(void *self , GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glFramebufferTexture2DOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &attachment, 4); ptr += 4;
+		memcpy(ptr, &textarget, 4); ptr += 4;
+		memcpy(ptr, &texture, 4); ptr += 4;
+		memcpy(ptr, &level, 4); ptr += 4;
+}
+
+void glGetFramebufferAttachmentParameterivOES_enc(void *self , GLenum target, GLenum attachment, GLenum pname, GLint* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetFramebufferAttachmentParameterivOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &attachment, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	stream->readback(params, __size_params);
+}
+
+void glGenerateMipmapOES_enc(void *self , GLenum target)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGenerateMipmapOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+}
+
+GLboolean glUnmapBufferOES_enc(void *self , GLenum target)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glUnmapBufferOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+
+	GLboolean retval;
+	stream->readback(&retval, 1);
+	return retval;
+}
+
+void glCurrentPaletteMatrixOES_enc(void *self , GLuint matrixpaletteindex)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glCurrentPaletteMatrixOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &matrixpaletteindex, 4); ptr += 4;
+}
+
+void glLoadPaletteFromModelViewMatrixOES_enc(void *self )
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 0;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glLoadPaletteFromModelViewMatrixOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+}
+
+GLbitfield glQueryMatrixxOES_enc(void *self , GLfixed* mantissa, GLint* exponent)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_mantissa =  (16 * sizeof(GLfixed));
+	const unsigned int __size_exponent =  (16 * sizeof(GLfixed));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + __size_mantissa + __size_exponent + 2*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glQueryMatrixxOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+	*(unsigned int *)(ptr) = __size_mantissa; ptr += 4;
+	*(unsigned int *)(ptr) = __size_exponent; ptr += 4;
+	stream->readback(mantissa, __size_mantissa);
+	stream->readback(exponent, __size_exponent);
+
+	GLbitfield retval;
+	stream->readback(&retval, 4);
+	return retval;
+}
+
+void glDepthRangefOES_enc(void *self , GLclampf zNear, GLclampf zFar)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glDepthRangefOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &zNear, 4); ptr += 4;
+		memcpy(ptr, &zFar, 4); ptr += 4;
+}
+
+void glFrustumfOES_enc(void *self , GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glFrustumfOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &left, 4); ptr += 4;
+		memcpy(ptr, &right, 4); ptr += 4;
+		memcpy(ptr, &bottom, 4); ptr += 4;
+		memcpy(ptr, &top, 4); ptr += 4;
+		memcpy(ptr, &zNear, 4); ptr += 4;
+		memcpy(ptr, &zFar, 4); ptr += 4;
+}
+
+void glOrthofOES_enc(void *self , GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glOrthofOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &left, 4); ptr += 4;
+		memcpy(ptr, &right, 4); ptr += 4;
+		memcpy(ptr, &bottom, 4); ptr += 4;
+		memcpy(ptr, &top, 4); ptr += 4;
+		memcpy(ptr, &zNear, 4); ptr += 4;
+		memcpy(ptr, &zFar, 4); ptr += 4;
+}
+
+void glClipPlanefOES_enc(void *self , GLenum plane, const GLfloat* equation)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_equation =  (4 * sizeof(GLfloat));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_equation + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glClipPlanefOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &plane, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_equation; ptr += 4;
+	memcpy(ptr, equation, __size_equation);ptr += __size_equation;
+}
+
+void glClipPlanefIMG_enc(void *self , GLenum plane, const GLfloat* equation)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_equation =  (4 * sizeof(GLfloat));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_equation + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glClipPlanefIMG;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &plane, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_equation; ptr += 4;
+	memcpy(ptr, equation, __size_equation);ptr += __size_equation;
+}
+
+void glGetClipPlanefOES_enc(void *self , GLenum pname, GLfloat* eqn)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_eqn =  (4 * sizeof(GLfloat));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_eqn + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetClipPlanefOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_eqn; ptr += 4;
+	stream->readback(eqn, __size_eqn);
+}
+
+void glClearDepthfOES_enc(void *self , GLclampf depth)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glClearDepthfOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &depth, 4); ptr += 4;
+}
+
+void glTexGenfOES_enc(void *self , GLenum coord, GLenum pname, GLfloat param)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glTexGenfOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &coord, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+		memcpy(ptr, &param, 4); ptr += 4;
+}
+
+void glTexGenfvOES_enc(void *self , GLenum coord, GLenum pname, const GLfloat* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLfloat));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glTexGenfvOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &coord, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	memcpy(ptr, params, __size_params);ptr += __size_params;
+}
+
+void glTexGeniOES_enc(void *self , GLenum coord, GLenum pname, GLint param)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glTexGeniOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &coord, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+		memcpy(ptr, &param, 4); ptr += 4;
+}
+
+void glTexGenivOES_enc(void *self , GLenum coord, GLenum pname, const GLint* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glTexGenivOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &coord, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	memcpy(ptr, params, __size_params);ptr += __size_params;
+}
+
+void glTexGenxOES_enc(void *self , GLenum coord, GLenum pname, GLfixed param)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glTexGenxOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &coord, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+		memcpy(ptr, &param, 4); ptr += 4;
+}
+
+void glTexGenxvOES_enc(void *self , GLenum coord, GLenum pname, const GLfixed* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLfixed));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glTexGenxvOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &coord, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	memcpy(ptr, params, __size_params);ptr += __size_params;
+}
+
+void glGetTexGenfvOES_enc(void *self , GLenum coord, GLenum pname, GLfloat* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLfloat));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetTexGenfvOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &coord, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	memcpy(ptr, params, __size_params);ptr += __size_params;
+}
+
+void glGetTexGenivOES_enc(void *self , GLenum coord, GLenum pname, GLint* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetTexGenivOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &coord, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	memcpy(ptr, params, __size_params);ptr += __size_params;
+}
+
+void glGetTexGenxvOES_enc(void *self , GLenum coord, GLenum pname, GLfixed* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLfixed));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetTexGenxvOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &coord, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	memcpy(ptr, params, __size_params);ptr += __size_params;
+}
+
+void glBindVertexArrayOES_enc(void *self , GLuint array)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glBindVertexArrayOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &array, 4); ptr += 4;
+}
+
+void glDeleteVertexArraysOES_enc(void *self , GLsizei n, const GLuint* arrays)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_arrays =  (n * sizeof(GLuint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_arrays + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glDeleteVertexArraysOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &n, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_arrays; ptr += 4;
+	memcpy(ptr, arrays, __size_arrays);ptr += __size_arrays;
+}
+
+void glGenVertexArraysOES_enc(void *self , GLsizei n, GLuint* arrays)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_arrays =  (n * sizeof(GLuint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_arrays + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGenVertexArraysOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &n, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_arrays; ptr += 4;
+	stream->readback(arrays, __size_arrays);
+}
+
+GLboolean glIsVertexArrayOES_enc(void *self , GLuint array)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glIsVertexArrayOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &array, 4); ptr += 4;
+
+	GLboolean retval;
+	stream->readback(&retval, 1);
+	return retval;
+}
+
+void glDiscardFramebufferEXT_enc(void *self , GLenum target, GLsizei numAttachments, const GLenum* attachments)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_attachments =  (numAttachments * sizeof(const GLenum));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_attachments + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glDiscardFramebufferEXT;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &numAttachments, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_attachments; ptr += 4;
+	memcpy(ptr, attachments, __size_attachments);ptr += __size_attachments;
+}
+
+void glRenderbufferStorageMultisampleIMG_enc(void *self , GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glRenderbufferStorageMultisampleIMG;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &samples, 4); ptr += 4;
+		memcpy(ptr, &internalformat, 4); ptr += 4;
+		memcpy(ptr, &width, 4); ptr += 4;
+		memcpy(ptr, &height, 4); ptr += 4;
+}
+
+void glFramebufferTexture2DMultisampleIMG_enc(void *self , GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glFramebufferTexture2DMultisampleIMG;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &attachment, 4); ptr += 4;
+		memcpy(ptr, &textarget, 4); ptr += 4;
+		memcpy(ptr, &texture, 4); ptr += 4;
+		memcpy(ptr, &level, 4); ptr += 4;
+		memcpy(ptr, &samples, 4); ptr += 4;
+}
+
+void glDeleteFencesNV_enc(void *self , GLsizei n, const GLuint* fences)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_fences =  (n * sizeof(GLuint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_fences + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glDeleteFencesNV;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &n, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_fences; ptr += 4;
+	memcpy(ptr, fences, __size_fences);ptr += __size_fences;
+}
+
+void glGenFencesNV_enc(void *self , GLsizei n, GLuint* fences)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_fences =  (n * sizeof(GLuint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_fences + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGenFencesNV;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &n, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_fences; ptr += 4;
+	memcpy(ptr, fences, __size_fences);ptr += __size_fences;
+}
+
+GLboolean glIsFenceNV_enc(void *self , GLuint fence)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glIsFenceNV;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &fence, 4); ptr += 4;
+
+	GLboolean retval;
+	stream->readback(&retval, 1);
+	return retval;
+}
+
+GLboolean glTestFenceNV_enc(void *self , GLuint fence)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glTestFenceNV;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &fence, 4); ptr += 4;
+
+	GLboolean retval;
+	stream->readback(&retval, 1);
+	return retval;
+}
+
+void glGetFenceivNV_enc(void *self , GLuint fence, GLenum pname, GLint* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetFenceivNV;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &fence, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	stream->readback(params, __size_params);
+}
+
+void glFinishFenceNV_enc(void *self , GLuint fence)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glFinishFenceNV;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &fence, 4); ptr += 4;
+}
+
+void glSetFenceNV_enc(void *self , GLuint fence, GLenum condition)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glSetFenceNV;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &fence, 4); ptr += 4;
+		memcpy(ptr, &condition, 4); ptr += 4;
+}
+
+void glGetDriverControlsQCOM_enc(void *self , GLint* num, GLsizei size, GLuint* driverControls)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_num =  (1 * sizeof(GLint));
+	const unsigned int __size_driverControls =  (size * sizeof(GLuint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + __size_num + 4 + __size_driverControls + 2*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetDriverControlsQCOM;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+	*(unsigned int *)(ptr) = __size_num; ptr += 4;
+		memcpy(ptr, &size, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_driverControls; ptr += 4;
+	stream->readback(num, __size_num);
+	stream->readback(driverControls, __size_driverControls);
+}
+
+void glGetDriverControlStringQCOM_enc(void *self , GLuint driverControl, GLsizei bufSize, GLsizei* length, GLchar* driverControlString)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_length =  (1 * sizeof(GLsizei));
+	const unsigned int __size_driverControlString =  (1 * sizeof(GLchar));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_length + __size_driverControlString + 2*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetDriverControlStringQCOM;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &driverControl, 4); ptr += 4;
+		memcpy(ptr, &bufSize, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_length; ptr += 4;
+	*(unsigned int *)(ptr) = __size_driverControlString; ptr += 4;
+	stream->readback(length, __size_length);
+	stream->readback(driverControlString, __size_driverControlString);
+}
+
+void glEnableDriverControlQCOM_enc(void *self , GLuint driverControl)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glEnableDriverControlQCOM;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &driverControl, 4); ptr += 4;
+}
+
+void glDisableDriverControlQCOM_enc(void *self , GLuint driverControl)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glDisableDriverControlQCOM;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &driverControl, 4); ptr += 4;
+}
+
+void glExtGetTexturesQCOM_enc(void *self , GLuint* textures, GLint maxTextures, GLint* numTextures)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_textures =  (maxTextures * sizeof(GLuint));
+	const unsigned int __size_numTextures =  (1 * sizeof(GLint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + __size_textures + 4 + __size_numTextures + 2*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glExtGetTexturesQCOM;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+	*(unsigned int *)(ptr) = __size_textures; ptr += 4;
+		memcpy(ptr, &maxTextures, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_numTextures; ptr += 4;
+	stream->readback(textures, __size_textures);
+	stream->readback(numTextures, __size_numTextures);
+}
+
+void glExtGetBuffersQCOM_enc(void *self , GLuint* buffers, GLint maxBuffers, GLint* numBuffers)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_buffers =  (maxBuffers * sizeof(GLuint));
+	const unsigned int __size_numBuffers =  (1 * sizeof(GLint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + __size_buffers + 4 + __size_numBuffers + 2*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glExtGetBuffersQCOM;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+	*(unsigned int *)(ptr) = __size_buffers; ptr += 4;
+		memcpy(ptr, &maxBuffers, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_numBuffers; ptr += 4;
+	stream->readback(buffers, __size_buffers);
+	stream->readback(numBuffers, __size_numBuffers);
+}
+
+void glExtGetRenderbuffersQCOM_enc(void *self , GLuint* renderbuffers, GLint maxRenderbuffers, GLint* numRenderbuffers)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_renderbuffers =  (maxRenderbuffers * sizeof(GLuint));
+	const unsigned int __size_numRenderbuffers =  (1 * sizeof(GLint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + __size_renderbuffers + 4 + __size_numRenderbuffers + 2*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glExtGetRenderbuffersQCOM;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+	*(unsigned int *)(ptr) = __size_renderbuffers; ptr += 4;
+		memcpy(ptr, &maxRenderbuffers, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_numRenderbuffers; ptr += 4;
+	stream->readback(renderbuffers, __size_renderbuffers);
+	stream->readback(numRenderbuffers, __size_numRenderbuffers);
+}
+
+void glExtGetFramebuffersQCOM_enc(void *self , GLuint* framebuffers, GLint maxFramebuffers, GLint* numFramebuffers)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_framebuffers =  (maxFramebuffers * sizeof(GLuint));
+	const unsigned int __size_numFramebuffers =  (1 * sizeof(GLint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + __size_framebuffers + 4 + __size_numFramebuffers + 2*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glExtGetFramebuffersQCOM;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+	*(unsigned int *)(ptr) = __size_framebuffers; ptr += 4;
+		memcpy(ptr, &maxFramebuffers, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_numFramebuffers; ptr += 4;
+	stream->readback(framebuffers, __size_framebuffers);
+	stream->readback(numFramebuffers, __size_numFramebuffers);
+}
+
+void glExtGetTexLevelParameterivQCOM_enc(void *self , GLuint texture, GLenum face, GLint level, GLenum pname, GLint* params)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glExtGetTexLevelParameterivQCOM;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &texture, 4); ptr += 4;
+		memcpy(ptr, &face, 4); ptr += 4;
+		memcpy(ptr, &level, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	stream->readback(params, __size_params);
+}
+
+void glExtTexObjectStateOverrideiQCOM_enc(void *self , GLenum target, GLenum pname, GLint param)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glExtTexObjectStateOverrideiQCOM;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+		memcpy(ptr, &param, 4); ptr += 4;
+}
+
+void glExtGetTexSubImageQCOM_enc(void *self , GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid* texels)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_texels =  (depth * pixelDataSize(self, width, height, format, type, 0));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + __size_texels + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glExtGetTexSubImageQCOM;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &level, 4); ptr += 4;
+		memcpy(ptr, &xoffset, 4); ptr += 4;
+		memcpy(ptr, &yoffset, 4); ptr += 4;
+		memcpy(ptr, &zoffset, 4); ptr += 4;
+		memcpy(ptr, &width, 4); ptr += 4;
+		memcpy(ptr, &height, 4); ptr += 4;
+		memcpy(ptr, &depth, 4); ptr += 4;
+		memcpy(ptr, &format, 4); ptr += 4;
+		memcpy(ptr, &type, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_texels; ptr += 4;
+	stream->readback(texels, __size_texels);
+}
+
+void glExtGetShadersQCOM_enc(void *self , GLuint* shaders, GLint maxShaders, GLint* numShaders)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_shaders =  (maxShaders * sizeof(GLuint));
+	const unsigned int __size_numShaders =  (1 * sizeof(GLint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + __size_shaders + 4 + __size_numShaders + 2*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glExtGetShadersQCOM;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+	*(unsigned int *)(ptr) = __size_shaders; ptr += 4;
+		memcpy(ptr, &maxShaders, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_numShaders; ptr += 4;
+	stream->readback(shaders, __size_shaders);
+	stream->readback(numShaders, __size_numShaders);
+}
+
+void glExtGetProgramsQCOM_enc(void *self , GLuint* programs, GLint maxPrograms, GLint* numPrograms)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_programs =  (maxPrograms * sizeof(GLuint));
+	const unsigned int __size_numPrograms =  (1 * sizeof(GLint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + __size_programs + 4 + __size_numPrograms + 2*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glExtGetProgramsQCOM;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+	*(unsigned int *)(ptr) = __size_programs; ptr += 4;
+		memcpy(ptr, &maxPrograms, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_numPrograms; ptr += 4;
+	stream->readback(programs, __size_programs);
+	stream->readback(numPrograms, __size_numPrograms);
+}
+
+GLboolean glExtIsProgramBinaryQCOM_enc(void *self , GLuint program)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glExtIsProgramBinaryQCOM;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &program, 4); ptr += 4;
+
+	GLboolean retval;
+	stream->readback(&retval, 1);
+	return retval;
+}
+
+void glStartTilingQCOM_enc(void *self , GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glStartTilingQCOM;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &x, 4); ptr += 4;
+		memcpy(ptr, &y, 4); ptr += 4;
+		memcpy(ptr, &width, 4); ptr += 4;
+		memcpy(ptr, &height, 4); ptr += 4;
+		memcpy(ptr, &preserveMask, 4); ptr += 4;
+}
+
+void glEndTilingQCOM_enc(void *self , GLbitfield preserveMask)
+{
+
+	gl_encoder_context_t *ctx = (gl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glEndTilingQCOM;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &preserveMask, 4); ptr += 4;
+}
+
+gl_encoder_context_t::gl_encoder_context_t(IOStream *stream)
+{
+	m_stream = stream;
+
+	set_glAlphaFunc(glAlphaFunc_enc);
+	set_glClearColor(glClearColor_enc);
+	set_glClearDepthf(glClearDepthf_enc);
+	set_glClipPlanef(glClipPlanef_enc);
+	set_glColor4f(glColor4f_enc);
+	set_glDepthRangef(glDepthRangef_enc);
+	set_glFogf(glFogf_enc);
+	set_glFogfv(glFogfv_enc);
+	set_glFrustumf(glFrustumf_enc);
+	set_glGetClipPlanef(glGetClipPlanef_enc);
+	set_glGetFloatv(glGetFloatv_enc);
+	set_glGetLightfv(glGetLightfv_enc);
+	set_glGetMaterialfv(glGetMaterialfv_enc);
+	set_glGetTexEnvfv(glGetTexEnvfv_enc);
+	set_glGetTexParameterfv(glGetTexParameterfv_enc);
+	set_glLightModelf(glLightModelf_enc);
+	set_glLightModelfv(glLightModelfv_enc);
+	set_glLightf(glLightf_enc);
+	set_glLightfv(glLightfv_enc);
+	set_glLineWidth(glLineWidth_enc);
+	set_glLoadMatrixf(glLoadMatrixf_enc);
+	set_glMaterialf(glMaterialf_enc);
+	set_glMaterialfv(glMaterialfv_enc);
+	set_glMultMatrixf(glMultMatrixf_enc);
+	set_glMultiTexCoord4f(glMultiTexCoord4f_enc);
+	set_glNormal3f(glNormal3f_enc);
+	set_glOrthof(glOrthof_enc);
+	set_glPointParameterf(glPointParameterf_enc);
+	set_glPointParameterfv(glPointParameterfv_enc);
+	set_glPointSize(glPointSize_enc);
+	set_glPolygonOffset(glPolygonOffset_enc);
+	set_glRotatef(glRotatef_enc);
+	set_glScalef(glScalef_enc);
+	set_glTexEnvf(glTexEnvf_enc);
+	set_glTexEnvfv(glTexEnvfv_enc);
+	set_glTexParameterf(glTexParameterf_enc);
+	set_glTexParameterfv(glTexParameterfv_enc);
+	set_glTranslatef(glTranslatef_enc);
+	set_glActiveTexture(glActiveTexture_enc);
+	set_glAlphaFuncx(glAlphaFuncx_enc);
+	set_glBindBuffer(glBindBuffer_enc);
+	set_glBindTexture(glBindTexture_enc);
+	set_glBlendFunc(glBlendFunc_enc);
+	set_glBufferData(glBufferData_enc);
+	set_glBufferSubData(glBufferSubData_enc);
+	set_glClear(glClear_enc);
+	set_glClearColorx(glClearColorx_enc);
+	set_glClearDepthx(glClearDepthx_enc);
+	set_glClearStencil(glClearStencil_enc);
+	set_glClientActiveTexture(glClientActiveTexture_enc);
+	set_glColor4ub(glColor4ub_enc);
+	set_glColor4x(glColor4x_enc);
+	set_glColorMask(glColorMask_enc);
+	set_glColorPointer((glColorPointer_client_proc_t)(enc_unsupported));
+	set_glCompressedTexImage2D(glCompressedTexImage2D_enc);
+	set_glCompressedTexSubImage2D(glCompressedTexSubImage2D_enc);
+	set_glCopyTexImage2D(glCopyTexImage2D_enc);
+	set_glCopyTexSubImage2D(glCopyTexSubImage2D_enc);
+	set_glCullFace(glCullFace_enc);
+	set_glDeleteBuffers(glDeleteBuffers_enc);
+	set_glDeleteTextures(glDeleteTextures_enc);
+	set_glDepthFunc(glDepthFunc_enc);
+	set_glDepthMask(glDepthMask_enc);
+	set_glDepthRangex(glDepthRangex_enc);
+	set_glDisable(glDisable_enc);
+	set_glDisableClientState(glDisableClientState_enc);
+	set_glDrawArrays(glDrawArrays_enc);
+	set_glDrawElements((glDrawElements_client_proc_t)(enc_unsupported));
+	set_glEnable(glEnable_enc);
+	set_glEnableClientState(glEnableClientState_enc);
+	set_glFinish(glFinish_enc);
+	set_glFlush(glFlush_enc);
+	set_glFogx(glFogx_enc);
+	set_glFogxv(glFogxv_enc);
+	set_glFrontFace(glFrontFace_enc);
+	set_glFrustumx(glFrustumx_enc);
+	set_glGetBooleanv(glGetBooleanv_enc);
+	set_glGetBufferParameteriv(glGetBufferParameteriv_enc);
+	set_glClipPlanex(glClipPlanex_enc);
+	set_glGenBuffers(glGenBuffers_enc);
+	set_glGenTextures(glGenTextures_enc);
+	set_glGetError(glGetError_enc);
+	set_glGetFixedv(glGetFixedv_enc);
+	set_glGetIntegerv(glGetIntegerv_enc);
+	set_glGetLightxv(glGetLightxv_enc);
+	set_glGetMaterialxv(glGetMaterialxv_enc);
+	set_glGetPointerv((glGetPointerv_client_proc_t)(enc_unsupported));
+	set_glGetString((glGetString_client_proc_t)(enc_unsupported));
+	set_glGetTexEnviv(glGetTexEnviv_enc);
+	set_glGetTexEnvxv(glGetTexEnvxv_enc);
+	set_glGetTexParameteriv(glGetTexParameteriv_enc);
+	set_glGetTexParameterxv(glGetTexParameterxv_enc);
+	set_glHint(glHint_enc);
+	set_glIsBuffer(glIsBuffer_enc);
+	set_glIsEnabled(glIsEnabled_enc);
+	set_glIsTexture(glIsTexture_enc);
+	set_glLightModelx(glLightModelx_enc);
+	set_glLightModelxv(glLightModelxv_enc);
+	set_glLightx(glLightx_enc);
+	set_glLightxv(glLightxv_enc);
+	set_glLineWidthx(glLineWidthx_enc);
+	set_glLoadIdentity(glLoadIdentity_enc);
+	set_glLoadMatrixx(glLoadMatrixx_enc);
+	set_glLogicOp(glLogicOp_enc);
+	set_glMaterialx(glMaterialx_enc);
+	set_glMaterialxv(glMaterialxv_enc);
+	set_glMatrixMode(glMatrixMode_enc);
+	set_glMultMatrixx(glMultMatrixx_enc);
+	set_glMultiTexCoord4x(glMultiTexCoord4x_enc);
+	set_glNormal3x(glNormal3x_enc);
+	set_glNormalPointer((glNormalPointer_client_proc_t)(enc_unsupported));
+	set_glOrthox(glOrthox_enc);
+	set_glPixelStorei(glPixelStorei_enc);
+	set_glPointParameterx(glPointParameterx_enc);
+	set_glPointParameterxv(glPointParameterxv_enc);
+	set_glPointSizex(glPointSizex_enc);
+	set_glPolygonOffsetx(glPolygonOffsetx_enc);
+	set_glPopMatrix(glPopMatrix_enc);
+	set_glPushMatrix(glPushMatrix_enc);
+	set_glReadPixels(glReadPixels_enc);
+	set_glRotatex(glRotatex_enc);
+	set_glSampleCoverage(glSampleCoverage_enc);
+	set_glSampleCoveragex(glSampleCoveragex_enc);
+	set_glScalex(glScalex_enc);
+	set_glScissor(glScissor_enc);
+	set_glShadeModel(glShadeModel_enc);
+	set_glStencilFunc(glStencilFunc_enc);
+	set_glStencilMask(glStencilMask_enc);
+	set_glStencilOp(glStencilOp_enc);
+	set_glTexCoordPointer((glTexCoordPointer_client_proc_t)(enc_unsupported));
+	set_glTexEnvi(glTexEnvi_enc);
+	set_glTexEnvx(glTexEnvx_enc);
+	set_glTexEnviv(glTexEnviv_enc);
+	set_glTexEnvxv(glTexEnvxv_enc);
+	set_glTexImage2D(glTexImage2D_enc);
+	set_glTexParameteri(glTexParameteri_enc);
+	set_glTexParameterx(glTexParameterx_enc);
+	set_glTexParameteriv(glTexParameteriv_enc);
+	set_glTexParameterxv(glTexParameterxv_enc);
+	set_glTexSubImage2D(glTexSubImage2D_enc);
+	set_glTranslatex(glTranslatex_enc);
+	set_glVertexPointer((glVertexPointer_client_proc_t)(enc_unsupported));
+	set_glViewport(glViewport_enc);
+	set_glPointSizePointerOES((glPointSizePointerOES_client_proc_t)(enc_unsupported));
+	set_glVertexPointerOffset(glVertexPointerOffset_enc);
+	set_glColorPointerOffset(glColorPointerOffset_enc);
+	set_glNormalPointerOffset(glNormalPointerOffset_enc);
+	set_glPointSizePointerOffset(glPointSizePointerOffset_enc);
+	set_glTexCoordPointerOffset(glTexCoordPointerOffset_enc);
+	set_glWeightPointerOffset(glWeightPointerOffset_enc);
+	set_glMatrixIndexPointerOffset(glMatrixIndexPointerOffset_enc);
+	set_glVertexPointerData(glVertexPointerData_enc);
+	set_glColorPointerData(glColorPointerData_enc);
+	set_glNormalPointerData(glNormalPointerData_enc);
+	set_glTexCoordPointerData(glTexCoordPointerData_enc);
+	set_glPointSizePointerData(glPointSizePointerData_enc);
+	set_glWeightPointerData(glWeightPointerData_enc);
+	set_glMatrixIndexPointerData(glMatrixIndexPointerData_enc);
+	set_glDrawElementsOffset(glDrawElementsOffset_enc);
+	set_glDrawElementsData(glDrawElementsData_enc);
+	set_glGetCompressedTextureFormats(glGetCompressedTextureFormats_enc);
+	set_glFinishRoundTrip(glFinishRoundTrip_enc);
+	set_glBlendEquationSeparateOES(glBlendEquationSeparateOES_enc);
+	set_glBlendFuncSeparateOES(glBlendFuncSeparateOES_enc);
+	set_glBlendEquationOES(glBlendEquationOES_enc);
+	set_glDrawTexsOES(glDrawTexsOES_enc);
+	set_glDrawTexiOES(glDrawTexiOES_enc);
+	set_glDrawTexxOES(glDrawTexxOES_enc);
+	set_glDrawTexsvOES(glDrawTexsvOES_enc);
+	set_glDrawTexivOES(glDrawTexivOES_enc);
+	set_glDrawTexxvOES(glDrawTexxvOES_enc);
+	set_glDrawTexfOES(glDrawTexfOES_enc);
+	set_glDrawTexfvOES(glDrawTexfvOES_enc);
+	set_glEGLImageTargetTexture2DOES(glEGLImageTargetTexture2DOES_enc);
+	set_glEGLImageTargetRenderbufferStorageOES(glEGLImageTargetRenderbufferStorageOES_enc);
+	set_glAlphaFuncxOES(glAlphaFuncxOES_enc);
+	set_glClearColorxOES(glClearColorxOES_enc);
+	set_glClearDepthxOES(glClearDepthxOES_enc);
+	set_glClipPlanexOES(glClipPlanexOES_enc);
+	set_glClipPlanexIMG(glClipPlanexIMG_enc);
+	set_glColor4xOES(glColor4xOES_enc);
+	set_glDepthRangexOES(glDepthRangexOES_enc);
+	set_glFogxOES(glFogxOES_enc);
+	set_glFogxvOES(glFogxvOES_enc);
+	set_glFrustumxOES(glFrustumxOES_enc);
+	set_glGetClipPlanexOES(glGetClipPlanexOES_enc);
+	set_glGetClipPlanex(glGetClipPlanex_enc);
+	set_glGetFixedvOES(glGetFixedvOES_enc);
+	set_glGetLightxvOES(glGetLightxvOES_enc);
+	set_glGetMaterialxvOES(glGetMaterialxvOES_enc);
+	set_glGetTexEnvxvOES(glGetTexEnvxvOES_enc);
+	set_glGetTexParameterxvOES(glGetTexParameterxvOES_enc);
+	set_glLightModelxOES(glLightModelxOES_enc);
+	set_glLightModelxvOES(glLightModelxvOES_enc);
+	set_glLightxOES(glLightxOES_enc);
+	set_glLightxvOES(glLightxvOES_enc);
+	set_glLineWidthxOES(glLineWidthxOES_enc);
+	set_glLoadMatrixxOES(glLoadMatrixxOES_enc);
+	set_glMaterialxOES(glMaterialxOES_enc);
+	set_glMaterialxvOES(glMaterialxvOES_enc);
+	set_glMultMatrixxOES(glMultMatrixxOES_enc);
+	set_glMultiTexCoord4xOES(glMultiTexCoord4xOES_enc);
+	set_glNormal3xOES(glNormal3xOES_enc);
+	set_glOrthoxOES(glOrthoxOES_enc);
+	set_glPointParameterxOES(glPointParameterxOES_enc);
+	set_glPointParameterxvOES(glPointParameterxvOES_enc);
+	set_glPointSizexOES(glPointSizexOES_enc);
+	set_glPolygonOffsetxOES(glPolygonOffsetxOES_enc);
+	set_glRotatexOES(glRotatexOES_enc);
+	set_glSampleCoveragexOES(glSampleCoveragexOES_enc);
+	set_glScalexOES(glScalexOES_enc);
+	set_glTexEnvxOES(glTexEnvxOES_enc);
+	set_glTexEnvxvOES(glTexEnvxvOES_enc);
+	set_glTexParameterxOES(glTexParameterxOES_enc);
+	set_glTexParameterxvOES(glTexParameterxvOES_enc);
+	set_glTranslatexOES(glTranslatexOES_enc);
+	set_glIsRenderbufferOES(glIsRenderbufferOES_enc);
+	set_glBindRenderbufferOES(glBindRenderbufferOES_enc);
+	set_glDeleteRenderbuffersOES(glDeleteRenderbuffersOES_enc);
+	set_glGenRenderbuffersOES(glGenRenderbuffersOES_enc);
+	set_glRenderbufferStorageOES(glRenderbufferStorageOES_enc);
+	set_glGetRenderbufferParameterivOES(glGetRenderbufferParameterivOES_enc);
+	set_glIsFramebufferOES(glIsFramebufferOES_enc);
+	set_glBindFramebufferOES(glBindFramebufferOES_enc);
+	set_glDeleteFramebuffersOES(glDeleteFramebuffersOES_enc);
+	set_glGenFramebuffersOES(glGenFramebuffersOES_enc);
+	set_glCheckFramebufferStatusOES(glCheckFramebufferStatusOES_enc);
+	set_glFramebufferRenderbufferOES(glFramebufferRenderbufferOES_enc);
+	set_glFramebufferTexture2DOES(glFramebufferTexture2DOES_enc);
+	set_glGetFramebufferAttachmentParameterivOES(glGetFramebufferAttachmentParameterivOES_enc);
+	set_glGenerateMipmapOES(glGenerateMipmapOES_enc);
+	set_glMapBufferOES((glMapBufferOES_client_proc_t)(enc_unsupported));
+	set_glUnmapBufferOES(glUnmapBufferOES_enc);
+	set_glGetBufferPointervOES((glGetBufferPointervOES_client_proc_t)(enc_unsupported));
+	set_glCurrentPaletteMatrixOES(glCurrentPaletteMatrixOES_enc);
+	set_glLoadPaletteFromModelViewMatrixOES(glLoadPaletteFromModelViewMatrixOES_enc);
+	set_glMatrixIndexPointerOES((glMatrixIndexPointerOES_client_proc_t)(enc_unsupported));
+	set_glWeightPointerOES((glWeightPointerOES_client_proc_t)(enc_unsupported));
+	set_glQueryMatrixxOES(glQueryMatrixxOES_enc);
+	set_glDepthRangefOES(glDepthRangefOES_enc);
+	set_glFrustumfOES(glFrustumfOES_enc);
+	set_glOrthofOES(glOrthofOES_enc);
+	set_glClipPlanefOES(glClipPlanefOES_enc);
+	set_glClipPlanefIMG(glClipPlanefIMG_enc);
+	set_glGetClipPlanefOES(glGetClipPlanefOES_enc);
+	set_glClearDepthfOES(glClearDepthfOES_enc);
+	set_glTexGenfOES(glTexGenfOES_enc);
+	set_glTexGenfvOES(glTexGenfvOES_enc);
+	set_glTexGeniOES(glTexGeniOES_enc);
+	set_glTexGenivOES(glTexGenivOES_enc);
+	set_glTexGenxOES(glTexGenxOES_enc);
+	set_glTexGenxvOES(glTexGenxvOES_enc);
+	set_glGetTexGenfvOES(glGetTexGenfvOES_enc);
+	set_glGetTexGenivOES(glGetTexGenivOES_enc);
+	set_glGetTexGenxvOES(glGetTexGenxvOES_enc);
+	set_glBindVertexArrayOES(glBindVertexArrayOES_enc);
+	set_glDeleteVertexArraysOES(glDeleteVertexArraysOES_enc);
+	set_glGenVertexArraysOES(glGenVertexArraysOES_enc);
+	set_glIsVertexArrayOES(glIsVertexArrayOES_enc);
+	set_glDiscardFramebufferEXT(glDiscardFramebufferEXT_enc);
+	set_glMultiDrawArraysEXT((glMultiDrawArraysEXT_client_proc_t)(enc_unsupported));
+	set_glMultiDrawElementsEXT((glMultiDrawElementsEXT_client_proc_t)(enc_unsupported));
+	set_glMultiDrawArraysSUN((glMultiDrawArraysSUN_client_proc_t)(enc_unsupported));
+	set_glMultiDrawElementsSUN((glMultiDrawElementsSUN_client_proc_t)(enc_unsupported));
+	set_glRenderbufferStorageMultisampleIMG(glRenderbufferStorageMultisampleIMG_enc);
+	set_glFramebufferTexture2DMultisampleIMG(glFramebufferTexture2DMultisampleIMG_enc);
+	set_glDeleteFencesNV(glDeleteFencesNV_enc);
+	set_glGenFencesNV(glGenFencesNV_enc);
+	set_glIsFenceNV(glIsFenceNV_enc);
+	set_glTestFenceNV(glTestFenceNV_enc);
+	set_glGetFenceivNV(glGetFenceivNV_enc);
+	set_glFinishFenceNV(glFinishFenceNV_enc);
+	set_glSetFenceNV(glSetFenceNV_enc);
+	set_glGetDriverControlsQCOM(glGetDriverControlsQCOM_enc);
+	set_glGetDriverControlStringQCOM(glGetDriverControlStringQCOM_enc);
+	set_glEnableDriverControlQCOM(glEnableDriverControlQCOM_enc);
+	set_glDisableDriverControlQCOM(glDisableDriverControlQCOM_enc);
+	set_glExtGetTexturesQCOM(glExtGetTexturesQCOM_enc);
+	set_glExtGetBuffersQCOM(glExtGetBuffersQCOM_enc);
+	set_glExtGetRenderbuffersQCOM(glExtGetRenderbuffersQCOM_enc);
+	set_glExtGetFramebuffersQCOM(glExtGetFramebuffersQCOM_enc);
+	set_glExtGetTexLevelParameterivQCOM(glExtGetTexLevelParameterivQCOM_enc);
+	set_glExtTexObjectStateOverrideiQCOM(glExtTexObjectStateOverrideiQCOM_enc);
+	set_glExtGetTexSubImageQCOM(glExtGetTexSubImageQCOM_enc);
+	set_glExtGetBufferPointervQCOM((glExtGetBufferPointervQCOM_client_proc_t)(enc_unsupported));
+	set_glExtGetShadersQCOM(glExtGetShadersQCOM_enc);
+	set_glExtGetProgramsQCOM(glExtGetProgramsQCOM_enc);
+	set_glExtIsProgramBinaryQCOM(glExtIsProgramBinaryQCOM_enc);
+	set_glExtGetProgramBinarySourceQCOM((glExtGetProgramBinarySourceQCOM_client_proc_t)(enc_unsupported));
+	set_glStartTilingQCOM(glStartTilingQCOM_enc);
+	set_glEndTilingQCOM(glEndTilingQCOM_enc);
+}
+
diff --git a/opengl/system/GLESv1_enc/gl_enc.h b/opengl/system/GLESv1_enc/gl_enc.h
new file mode 100644
index 0000000..d8a23e4
--- /dev/null
+++ b/opengl/system/GLESv1_enc/gl_enc.h
@@ -0,0 +1,316 @@
+// Generated Code - DO NOT EDIT !!
+// generated by 'emugen'
+
+#ifndef GUARD_gl_encoder_context_t
+#define GUARD_gl_encoder_context_t
+
+#include "IOStream.h"
+#include "gl_client_context.h"
+
+
+#include "glUtils.h"
+#include "GLEncoderUtils.h"
+
+struct gl_encoder_context_t : public gl_client_context_t {
+
+	IOStream *m_stream;
+
+	gl_encoder_context_t(IOStream *stream);
+
+
+};
+
+extern "C" {
+	void glAlphaFunc_enc(void *self , GLenum func, GLclampf ref);
+	void glClearColor_enc(void *self , GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+	void glClearDepthf_enc(void *self , GLclampf depth);
+	void glClipPlanef_enc(void *self , GLenum plane, const GLfloat* equation);
+	void glColor4f_enc(void *self , GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+	void glDepthRangef_enc(void *self , GLclampf zNear, GLclampf zFar);
+	void glFogf_enc(void *self , GLenum pname, GLfloat param);
+	void glFogfv_enc(void *self , GLenum pname, const GLfloat* params);
+	void glFrustumf_enc(void *self , GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);
+	void glGetClipPlanef_enc(void *self , GLenum pname, GLfloat* eqn);
+	void glGetFloatv_enc(void *self , GLenum pname, GLfloat* params);
+	void glGetLightfv_enc(void *self , GLenum light, GLenum pname, GLfloat* params);
+	void glGetMaterialfv_enc(void *self , GLenum face, GLenum pname, GLfloat* params);
+	void glGetTexEnvfv_enc(void *self , GLenum env, GLenum pname, GLfloat* params);
+	void glGetTexParameterfv_enc(void *self , GLenum target, GLenum pname, GLfloat* params);
+	void glLightModelf_enc(void *self , GLenum pname, GLfloat param);
+	void glLightModelfv_enc(void *self , GLenum pname, const GLfloat* params);
+	void glLightf_enc(void *self , GLenum light, GLenum pname, GLfloat param);
+	void glLightfv_enc(void *self , GLenum light, GLenum pname, const GLfloat* params);
+	void glLineWidth_enc(void *self , GLfloat width);
+	void glLoadMatrixf_enc(void *self , const GLfloat* m);
+	void glMaterialf_enc(void *self , GLenum face, GLenum pname, GLfloat param);
+	void glMaterialfv_enc(void *self , GLenum face, GLenum pname, const GLfloat* params);
+	void glMultMatrixf_enc(void *self , const GLfloat* m);
+	void glMultiTexCoord4f_enc(void *self , GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+	void glNormal3f_enc(void *self , GLfloat nx, GLfloat ny, GLfloat nz);
+	void glOrthof_enc(void *self , GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);
+	void glPointParameterf_enc(void *self , GLenum pname, GLfloat param);
+	void glPointParameterfv_enc(void *self , GLenum pname, const GLfloat* params);
+	void glPointSize_enc(void *self , GLfloat size);
+	void glPolygonOffset_enc(void *self , GLfloat factor, GLfloat units);
+	void glRotatef_enc(void *self , GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
+	void glScalef_enc(void *self , GLfloat x, GLfloat y, GLfloat z);
+	void glTexEnvf_enc(void *self , GLenum target, GLenum pname, GLfloat param);
+	void glTexEnvfv_enc(void *self , GLenum target, GLenum pname, const GLfloat* params);
+	void glTexParameterf_enc(void *self , GLenum target, GLenum pname, GLfloat param);
+	void glTexParameterfv_enc(void *self , GLenum target, GLenum pname, const GLfloat* params);
+	void glTranslatef_enc(void *self , GLfloat x, GLfloat y, GLfloat z);
+	void glActiveTexture_enc(void *self , GLenum texture);
+	void glAlphaFuncx_enc(void *self , GLenum func, GLclampx ref);
+	void glBindBuffer_enc(void *self , GLenum target, GLuint buffer);
+	void glBindTexture_enc(void *self , GLenum target, GLuint texture);
+	void glBlendFunc_enc(void *self , GLenum sfactor, GLenum dfactor);
+	void glBufferData_enc(void *self , GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage);
+	void glBufferSubData_enc(void *self , GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data);
+	void glClear_enc(void *self , GLbitfield mask);
+	void glClearColorx_enc(void *self , GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha);
+	void glClearDepthx_enc(void *self , GLclampx depth);
+	void glClearStencil_enc(void *self , GLint s);
+	void glClientActiveTexture_enc(void *self , GLenum texture);
+	void glColor4ub_enc(void *self , GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha);
+	void glColor4x_enc(void *self , GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha);
+	void glColorMask_enc(void *self , GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+	void glColorPointer_enc(void *self , GLint size, GLenum type, GLsizei stride, const GLvoid* pointer);
+	void glCompressedTexImage2D_enc(void *self , GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data);
+	void glCompressedTexSubImage2D_enc(void *self , GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data);
+	void glCopyTexImage2D_enc(void *self , GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+	void glCopyTexSubImage2D_enc(void *self , GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+	void glCullFace_enc(void *self , GLenum mode);
+	void glDeleteBuffers_enc(void *self , GLsizei n, const GLuint* buffers);
+	void glDeleteTextures_enc(void *self , GLsizei n, const GLuint* textures);
+	void glDepthFunc_enc(void *self , GLenum func);
+	void glDepthMask_enc(void *self , GLboolean flag);
+	void glDepthRangex_enc(void *self , GLclampx zNear, GLclampx zFar);
+	void glDisable_enc(void *self , GLenum cap);
+	void glDisableClientState_enc(void *self , GLenum array);
+	void glDrawArrays_enc(void *self , GLenum mode, GLint first, GLsizei count);
+	void glDrawElements_enc(void *self , GLenum mode, GLsizei count, GLenum type, const GLvoid* indices);
+	void glEnable_enc(void *self , GLenum cap);
+	void glEnableClientState_enc(void *self , GLenum array);
+	void glFinish_enc(void *self );
+	void glFlush_enc(void *self );
+	void glFogx_enc(void *self , GLenum pname, GLfixed param);
+	void glFogxv_enc(void *self , GLenum pname, const GLfixed* params);
+	void glFrontFace_enc(void *self , GLenum mode);
+	void glFrustumx_enc(void *self , GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar);
+	void glGetBooleanv_enc(void *self , GLenum pname, GLboolean* params);
+	void glGetBufferParameteriv_enc(void *self , GLenum target, GLenum pname, GLint* params);
+	void glClipPlanex_enc(void *self , GLenum pname, const GLfixed* eqn);
+	void glGenBuffers_enc(void *self , GLsizei n, GLuint* buffers);
+	void glGenTextures_enc(void *self , GLsizei n, GLuint* textures);
+	GLenum glGetError_enc(void *self );
+	void glGetFixedv_enc(void *self , GLenum pname, GLfixed* params);
+	void glGetIntegerv_enc(void *self , GLenum pname, GLint* params);
+	void glGetLightxv_enc(void *self , GLenum light, GLenum pname, GLfixed* params);
+	void glGetMaterialxv_enc(void *self , GLenum face, GLenum pname, GLfixed* params);
+	void glGetPointerv_enc(void *self , GLenum pname, GLvoid** params);
+	const GLubyte* glGetString_enc(void *self , GLenum name);
+	void glGetTexEnviv_enc(void *self , GLenum env, GLenum pname, GLint* params);
+	void glGetTexEnvxv_enc(void *self , GLenum env, GLenum pname, GLfixed* params);
+	void glGetTexParameteriv_enc(void *self , GLenum target, GLenum pname, GLint* params);
+	void glGetTexParameterxv_enc(void *self , GLenum target, GLenum pname, GLfixed* params);
+	void glHint_enc(void *self , GLenum target, GLenum mode);
+	GLboolean glIsBuffer_enc(void *self , GLuint buffer);
+	GLboolean glIsEnabled_enc(void *self , GLenum cap);
+	GLboolean glIsTexture_enc(void *self , GLuint texture);
+	void glLightModelx_enc(void *self , GLenum pname, GLfixed param);
+	void glLightModelxv_enc(void *self , GLenum pname, const GLfixed* params);
+	void glLightx_enc(void *self , GLenum light, GLenum pname, GLfixed param);
+	void glLightxv_enc(void *self , GLenum light, GLenum pname, const GLfixed* params);
+	void glLineWidthx_enc(void *self , GLfixed width);
+	void glLoadIdentity_enc(void *self );
+	void glLoadMatrixx_enc(void *self , const GLfixed* m);
+	void glLogicOp_enc(void *self , GLenum opcode);
+	void glMaterialx_enc(void *self , GLenum face, GLenum pname, GLfixed param);
+	void glMaterialxv_enc(void *self , GLenum face, GLenum pname, const GLfixed* params);
+	void glMatrixMode_enc(void *self , GLenum mode);
+	void glMultMatrixx_enc(void *self , const GLfixed* m);
+	void glMultiTexCoord4x_enc(void *self , GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q);
+	void glNormal3x_enc(void *self , GLfixed nx, GLfixed ny, GLfixed nz);
+	void glNormalPointer_enc(void *self , GLenum type, GLsizei stride, const GLvoid* pointer);
+	void glOrthox_enc(void *self , GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar);
+	void glPixelStorei_enc(void *self , GLenum pname, GLint param);
+	void glPointParameterx_enc(void *self , GLenum pname, GLfixed param);
+	void glPointParameterxv_enc(void *self , GLenum pname, const GLfixed* params);
+	void glPointSizex_enc(void *self , GLfixed size);
+	void glPolygonOffsetx_enc(void *self , GLfixed factor, GLfixed units);
+	void glPopMatrix_enc(void *self );
+	void glPushMatrix_enc(void *self );
+	void glReadPixels_enc(void *self , GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels);
+	void glRotatex_enc(void *self , GLfixed angle, GLfixed x, GLfixed y, GLfixed z);
+	void glSampleCoverage_enc(void *self , GLclampf value, GLboolean invert);
+	void glSampleCoveragex_enc(void *self , GLclampx value, GLboolean invert);
+	void glScalex_enc(void *self , GLfixed x, GLfixed y, GLfixed z);
+	void glScissor_enc(void *self , GLint x, GLint y, GLsizei width, GLsizei height);
+	void glShadeModel_enc(void *self , GLenum mode);
+	void glStencilFunc_enc(void *self , GLenum func, GLint ref, GLuint mask);
+	void glStencilMask_enc(void *self , GLuint mask);
+	void glStencilOp_enc(void *self , GLenum fail, GLenum zfail, GLenum zpass);
+	void glTexCoordPointer_enc(void *self , GLint size, GLenum type, GLsizei stride, const GLvoid* pointer);
+	void glTexEnvi_enc(void *self , GLenum target, GLenum pname, GLint param);
+	void glTexEnvx_enc(void *self , GLenum target, GLenum pname, GLfixed param);
+	void glTexEnviv_enc(void *self , GLenum target, GLenum pname, const GLint* params);
+	void glTexEnvxv_enc(void *self , GLenum target, GLenum pname, const GLfixed* params);
+	void glTexImage2D_enc(void *self , GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels);
+	void glTexParameteri_enc(void *self , GLenum target, GLenum pname, GLint param);
+	void glTexParameterx_enc(void *self , GLenum target, GLenum pname, GLfixed param);
+	void glTexParameteriv_enc(void *self , GLenum target, GLenum pname, const GLint* params);
+	void glTexParameterxv_enc(void *self , GLenum target, GLenum pname, const GLfixed* params);
+	void glTexSubImage2D_enc(void *self , GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels);
+	void glTranslatex_enc(void *self , GLfixed x, GLfixed y, GLfixed z);
+	void glVertexPointer_enc(void *self , GLint size, GLenum type, GLsizei stride, const GLvoid* pointer);
+	void glViewport_enc(void *self , GLint x, GLint y, GLsizei width, GLsizei height);
+	void glPointSizePointerOES_enc(void *self , GLenum type, GLsizei stride, const GLvoid* pointer);
+	void glVertexPointerOffset_enc(void *self , GLint size, GLenum type, GLsizei stride, GLuint offset);
+	void glColorPointerOffset_enc(void *self , GLint size, GLenum type, GLsizei stride, GLuint offset);
+	void glNormalPointerOffset_enc(void *self , GLenum type, GLsizei stride, GLuint offset);
+	void glPointSizePointerOffset_enc(void *self , GLenum type, GLsizei stride, GLuint offset);
+	void glTexCoordPointerOffset_enc(void *self , GLint size, GLenum type, GLsizei stride, GLuint offset);
+	void glWeightPointerOffset_enc(void *self , GLint size, GLenum type, GLsizei stride, GLuint offset);
+	void glMatrixIndexPointerOffset_enc(void *self , GLint size, GLenum type, GLsizei stride, GLuint offset);
+	void glVertexPointerData_enc(void *self , GLint size, GLenum type, GLsizei stride, void* data, GLuint datalen);
+	void glColorPointerData_enc(void *self , GLint size, GLenum type, GLsizei stride, void* data, GLuint datalen);
+	void glNormalPointerData_enc(void *self , GLenum type, GLsizei stride, void* data, GLuint datalen);
+	void glTexCoordPointerData_enc(void *self , GLint unit, GLint size, GLenum type, GLsizei stride, void* data, GLuint datalen);
+	void glPointSizePointerData_enc(void *self , GLenum type, GLsizei stride, void* data, GLuint datalen);
+	void glWeightPointerData_enc(void *self , GLint size, GLenum type, GLsizei stride, void* data, GLuint datalen);
+	void glMatrixIndexPointerData_enc(void *self , GLint size, GLenum type, GLsizei stride, void* data, GLuint datalen);
+	void glDrawElementsOffset_enc(void *self , GLenum mode, GLsizei count, GLenum type, GLuint offset);
+	void glDrawElementsData_enc(void *self , GLenum mode, GLsizei count, GLenum type, void* data, GLuint datalen);
+	void glGetCompressedTextureFormats_enc(void *self , int count, GLint* formats);
+	int glFinishRoundTrip_enc(void *self );
+	void glBlendEquationSeparateOES_enc(void *self , GLenum modeRGB, GLenum modeAlpha);
+	void glBlendFuncSeparateOES_enc(void *self , GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+	void glBlendEquationOES_enc(void *self , GLenum mode);
+	void glDrawTexsOES_enc(void *self , GLshort x, GLshort y, GLshort z, GLshort width, GLshort height);
+	void glDrawTexiOES_enc(void *self , GLint x, GLint y, GLint z, GLint width, GLint height);
+	void glDrawTexxOES_enc(void *self , GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height);
+	void glDrawTexsvOES_enc(void *self , const GLshort* coords);
+	void glDrawTexivOES_enc(void *self , const GLint* coords);
+	void glDrawTexxvOES_enc(void *self , const GLfixed* coords);
+	void glDrawTexfOES_enc(void *self , GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height);
+	void glDrawTexfvOES_enc(void *self , const GLfloat* coords);
+	void glEGLImageTargetTexture2DOES_enc(void *self , GLenum target, GLeglImageOES image);
+	void glEGLImageTargetRenderbufferStorageOES_enc(void *self , GLenum target, GLeglImageOES image);
+	void glAlphaFuncxOES_enc(void *self , GLenum func, GLclampx ref);
+	void glClearColorxOES_enc(void *self , GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha);
+	void glClearDepthxOES_enc(void *self , GLclampx depth);
+	void glClipPlanexOES_enc(void *self , GLenum plane, const GLfixed* equation);
+	void glClipPlanexIMG_enc(void *self , GLenum plane, const GLfixed* equation);
+	void glColor4xOES_enc(void *self , GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha);
+	void glDepthRangexOES_enc(void *self , GLclampx zNear, GLclampx zFar);
+	void glFogxOES_enc(void *self , GLenum pname, GLfixed param);
+	void glFogxvOES_enc(void *self , GLenum pname, const GLfixed* params);
+	void glFrustumxOES_enc(void *self , GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar);
+	void glGetClipPlanexOES_enc(void *self , GLenum pname, GLfixed* eqn);
+	void glGetClipPlanex_enc(void *self , GLenum pname, GLfixed* eqn);
+	void glGetFixedvOES_enc(void *self , GLenum pname, GLfixed* params);
+	void glGetLightxvOES_enc(void *self , GLenum light, GLenum pname, GLfixed* params);
+	void glGetMaterialxvOES_enc(void *self , GLenum face, GLenum pname, GLfixed* params);
+	void glGetTexEnvxvOES_enc(void *self , GLenum env, GLenum pname, GLfixed* params);
+	void glGetTexParameterxvOES_enc(void *self , GLenum target, GLenum pname, GLfixed* params);
+	void glLightModelxOES_enc(void *self , GLenum pname, GLfixed param);
+	void glLightModelxvOES_enc(void *self , GLenum pname, const GLfixed* params);
+	void glLightxOES_enc(void *self , GLenum light, GLenum pname, GLfixed param);
+	void glLightxvOES_enc(void *self , GLenum light, GLenum pname, const GLfixed* params);
+	void glLineWidthxOES_enc(void *self , GLfixed width);
+	void glLoadMatrixxOES_enc(void *self , const GLfixed* m);
+	void glMaterialxOES_enc(void *self , GLenum face, GLenum pname, GLfixed param);
+	void glMaterialxvOES_enc(void *self , GLenum face, GLenum pname, const GLfixed* params);
+	void glMultMatrixxOES_enc(void *self , const GLfixed* m);
+	void glMultiTexCoord4xOES_enc(void *self , GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q);
+	void glNormal3xOES_enc(void *self , GLfixed nx, GLfixed ny, GLfixed nz);
+	void glOrthoxOES_enc(void *self , GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar);
+	void glPointParameterxOES_enc(void *self , GLenum pname, GLfixed param);
+	void glPointParameterxvOES_enc(void *self , GLenum pname, const GLfixed* params);
+	void glPointSizexOES_enc(void *self , GLfixed size);
+	void glPolygonOffsetxOES_enc(void *self , GLfixed factor, GLfixed units);
+	void glRotatexOES_enc(void *self , GLfixed angle, GLfixed x, GLfixed y, GLfixed z);
+	void glSampleCoveragexOES_enc(void *self , GLclampx value, GLboolean invert);
+	void glScalexOES_enc(void *self , GLfixed x, GLfixed y, GLfixed z);
+	void glTexEnvxOES_enc(void *self , GLenum target, GLenum pname, GLfixed param);
+	void glTexEnvxvOES_enc(void *self , GLenum target, GLenum pname, const GLfixed* params);
+	void glTexParameterxOES_enc(void *self , GLenum target, GLenum pname, GLfixed param);
+	void glTexParameterxvOES_enc(void *self , GLenum target, GLenum pname, const GLfixed* params);
+	void glTranslatexOES_enc(void *self , GLfixed x, GLfixed y, GLfixed z);
+	GLboolean glIsRenderbufferOES_enc(void *self , GLuint renderbuffer);
+	void glBindRenderbufferOES_enc(void *self , GLenum target, GLuint renderbuffer);
+	void glDeleteRenderbuffersOES_enc(void *self , GLsizei n, const GLuint* renderbuffers);
+	void glGenRenderbuffersOES_enc(void *self , GLsizei n, GLuint* renderbuffers);
+	void glRenderbufferStorageOES_enc(void *self , GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+	void glGetRenderbufferParameterivOES_enc(void *self , GLenum target, GLenum pname, GLint* params);
+	GLboolean glIsFramebufferOES_enc(void *self , GLuint framebuffer);
+	void glBindFramebufferOES_enc(void *self , GLenum target, GLuint framebuffer);
+	void glDeleteFramebuffersOES_enc(void *self , GLsizei n, const GLuint* framebuffers);
+	void glGenFramebuffersOES_enc(void *self , GLsizei n, GLuint* framebuffers);
+	GLenum glCheckFramebufferStatusOES_enc(void *self , GLenum target);
+	void glFramebufferRenderbufferOES_enc(void *self , GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+	void glFramebufferTexture2DOES_enc(void *self , GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+	void glGetFramebufferAttachmentParameterivOES_enc(void *self , GLenum target, GLenum attachment, GLenum pname, GLint* params);
+	void glGenerateMipmapOES_enc(void *self , GLenum target);
+	void* glMapBufferOES_enc(void *self , GLenum target, GLenum access);
+	GLboolean glUnmapBufferOES_enc(void *self , GLenum target);
+	void glGetBufferPointervOES_enc(void *self , GLenum target, GLenum pname, GLvoid** params);
+	void glCurrentPaletteMatrixOES_enc(void *self , GLuint matrixpaletteindex);
+	void glLoadPaletteFromModelViewMatrixOES_enc(void *self );
+	void glMatrixIndexPointerOES_enc(void *self , GLint size, GLenum type, GLsizei stride, const GLvoid* pointer);
+	void glWeightPointerOES_enc(void *self , GLint size, GLenum type, GLsizei stride, const GLvoid* pointer);
+	GLbitfield glQueryMatrixxOES_enc(void *self , GLfixed* mantissa, GLint* exponent);
+	void glDepthRangefOES_enc(void *self , GLclampf zNear, GLclampf zFar);
+	void glFrustumfOES_enc(void *self , GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);
+	void glOrthofOES_enc(void *self , GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);
+	void glClipPlanefOES_enc(void *self , GLenum plane, const GLfloat* equation);
+	void glClipPlanefIMG_enc(void *self , GLenum plane, const GLfloat* equation);
+	void glGetClipPlanefOES_enc(void *self , GLenum pname, GLfloat* eqn);
+	void glClearDepthfOES_enc(void *self , GLclampf depth);
+	void glTexGenfOES_enc(void *self , GLenum coord, GLenum pname, GLfloat param);
+	void glTexGenfvOES_enc(void *self , GLenum coord, GLenum pname, const GLfloat* params);
+	void glTexGeniOES_enc(void *self , GLenum coord, GLenum pname, GLint param);
+	void glTexGenivOES_enc(void *self , GLenum coord, GLenum pname, const GLint* params);
+	void glTexGenxOES_enc(void *self , GLenum coord, GLenum pname, GLfixed param);
+	void glTexGenxvOES_enc(void *self , GLenum coord, GLenum pname, const GLfixed* params);
+	void glGetTexGenfvOES_enc(void *self , GLenum coord, GLenum pname, GLfloat* params);
+	void glGetTexGenivOES_enc(void *self , GLenum coord, GLenum pname, GLint* params);
+	void glGetTexGenxvOES_enc(void *self , GLenum coord, GLenum pname, GLfixed* params);
+	void glBindVertexArrayOES_enc(void *self , GLuint array);
+	void glDeleteVertexArraysOES_enc(void *self , GLsizei n, const GLuint* arrays);
+	void glGenVertexArraysOES_enc(void *self , GLsizei n, GLuint* arrays);
+	GLboolean glIsVertexArrayOES_enc(void *self , GLuint array);
+	void glDiscardFramebufferEXT_enc(void *self , GLenum target, GLsizei numAttachments, const GLenum* attachments);
+	void glMultiDrawArraysEXT_enc(void *self , GLenum mode, GLint* first, GLsizei* count, GLsizei primcount);
+	void glMultiDrawElementsEXT_enc(void *self , GLenum mode, const GLsizei* count, GLenum type, const GLvoid** indices, GLsizei primcount);
+	void glMultiDrawArraysSUN_enc(void *self , GLenum mode, GLint* first, GLsizei* count, GLsizei primcount);
+	void glMultiDrawElementsSUN_enc(void *self , GLenum mode, const GLsizei* count, GLenum type, const GLvoid** indices, GLsizei primcount);
+	void glRenderbufferStorageMultisampleIMG_enc(void *self , GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+	void glFramebufferTexture2DMultisampleIMG_enc(void *self , GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples);
+	void glDeleteFencesNV_enc(void *self , GLsizei n, const GLuint* fences);
+	void glGenFencesNV_enc(void *self , GLsizei n, GLuint* fences);
+	GLboolean glIsFenceNV_enc(void *self , GLuint fence);
+	GLboolean glTestFenceNV_enc(void *self , GLuint fence);
+	void glGetFenceivNV_enc(void *self , GLuint fence, GLenum pname, GLint* params);
+	void glFinishFenceNV_enc(void *self , GLuint fence);
+	void glSetFenceNV_enc(void *self , GLuint fence, GLenum condition);
+	void glGetDriverControlsQCOM_enc(void *self , GLint* num, GLsizei size, GLuint* driverControls);
+	void glGetDriverControlStringQCOM_enc(void *self , GLuint driverControl, GLsizei bufSize, GLsizei* length, GLchar* driverControlString);
+	void glEnableDriverControlQCOM_enc(void *self , GLuint driverControl);
+	void glDisableDriverControlQCOM_enc(void *self , GLuint driverControl);
+	void glExtGetTexturesQCOM_enc(void *self , GLuint* textures, GLint maxTextures, GLint* numTextures);
+	void glExtGetBuffersQCOM_enc(void *self , GLuint* buffers, GLint maxBuffers, GLint* numBuffers);
+	void glExtGetRenderbuffersQCOM_enc(void *self , GLuint* renderbuffers, GLint maxRenderbuffers, GLint* numRenderbuffers);
+	void glExtGetFramebuffersQCOM_enc(void *self , GLuint* framebuffers, GLint maxFramebuffers, GLint* numFramebuffers);
+	void glExtGetTexLevelParameterivQCOM_enc(void *self , GLuint texture, GLenum face, GLint level, GLenum pname, GLint* params);
+	void glExtTexObjectStateOverrideiQCOM_enc(void *self , GLenum target, GLenum pname, GLint param);
+	void glExtGetTexSubImageQCOM_enc(void *self , GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid* texels);
+	void glExtGetBufferPointervQCOM_enc(void *self , GLenum target, GLvoid** params);
+	void glExtGetShadersQCOM_enc(void *self , GLuint* shaders, GLint maxShaders, GLint* numShaders);
+	void glExtGetProgramsQCOM_enc(void *self , GLuint* programs, GLint maxPrograms, GLint* numPrograms);
+	GLboolean glExtIsProgramBinaryQCOM_enc(void *self , GLuint program);
+	void glExtGetProgramBinarySourceQCOM_enc(void *self , GLuint program, GLenum shadertype, GLchar* source, GLint* length);
+	void glStartTilingQCOM_enc(void *self , GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask);
+	void glEndTilingQCOM_enc(void *self , GLbitfield preserveMask);
+};
+#endif
\ No newline at end of file
diff --git a/opengl/system/GLESv1_enc/gl_entry.cpp b/opengl/system/GLESv1_enc/gl_entry.cpp
new file mode 100644
index 0000000..b43df09
--- /dev/null
+++ b/opengl/system/GLESv1_enc/gl_entry.cpp
@@ -0,0 +1,2066 @@
+// Generated Code - DO NOT EDIT !!
+// generated by 'emugen'
+#include <stdio.h>
+#include <stdlib.h>
+#include "gl_client_context.h"
+
+#ifndef GL_TRUE
+extern "C" {
+	void glAlphaFunc(GLenum func, GLclampf ref);
+	void glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+	void glClearDepthf(GLclampf depth);
+	void glClipPlanef(GLenum plane, const GLfloat* equation);
+	void glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+	void glDepthRangef(GLclampf zNear, GLclampf zFar);
+	void glFogf(GLenum pname, GLfloat param);
+	void glFogfv(GLenum pname, const GLfloat* params);
+	void glFrustumf(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);
+	void glGetClipPlanef(GLenum pname, GLfloat* eqn);
+	void glGetFloatv(GLenum pname, GLfloat* params);
+	void glGetLightfv(GLenum light, GLenum pname, GLfloat* params);
+	void glGetMaterialfv(GLenum face, GLenum pname, GLfloat* params);
+	void glGetTexEnvfv(GLenum env, GLenum pname, GLfloat* params);
+	void glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params);
+	void glLightModelf(GLenum pname, GLfloat param);
+	void glLightModelfv(GLenum pname, const GLfloat* params);
+	void glLightf(GLenum light, GLenum pname, GLfloat param);
+	void glLightfv(GLenum light, GLenum pname, const GLfloat* params);
+	void glLineWidth(GLfloat width);
+	void glLoadMatrixf(const GLfloat* m);
+	void glMaterialf(GLenum face, GLenum pname, GLfloat param);
+	void glMaterialfv(GLenum face, GLenum pname, const GLfloat* params);
+	void glMultMatrixf(const GLfloat* m);
+	void glMultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+	void glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz);
+	void glOrthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);
+	void glPointParameterf(GLenum pname, GLfloat param);
+	void glPointParameterfv(GLenum pname, const GLfloat* params);
+	void glPointSize(GLfloat size);
+	void glPolygonOffset(GLfloat factor, GLfloat units);
+	void glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
+	void glScalef(GLfloat x, GLfloat y, GLfloat z);
+	void glTexEnvf(GLenum target, GLenum pname, GLfloat param);
+	void glTexEnvfv(GLenum target, GLenum pname, const GLfloat* params);
+	void glTexParameterf(GLenum target, GLenum pname, GLfloat param);
+	void glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
+	void glTranslatef(GLfloat x, GLfloat y, GLfloat z);
+	void glActiveTexture(GLenum texture);
+	void glAlphaFuncx(GLenum func, GLclampx ref);
+	void glBindBuffer(GLenum target, GLuint buffer);
+	void glBindTexture(GLenum target, GLuint texture);
+	void glBlendFunc(GLenum sfactor, GLenum dfactor);
+	void glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage);
+	void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data);
+	void glClear(GLbitfield mask);
+	void glClearColorx(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha);
+	void glClearDepthx(GLclampx depth);
+	void glClearStencil(GLint s);
+	void glClientActiveTexture(GLenum texture);
+	void glColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha);
+	void glColor4x(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha);
+	void glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+	void glColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid* pointer);
+	void glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data);
+	void glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data);
+	void glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+	void glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+	void glCullFace(GLenum mode);
+	void glDeleteBuffers(GLsizei n, const GLuint* buffers);
+	void glDeleteTextures(GLsizei n, const GLuint* textures);
+	void glDepthFunc(GLenum func);
+	void glDepthMask(GLboolean flag);
+	void glDepthRangex(GLclampx zNear, GLclampx zFar);
+	void glDisable(GLenum cap);
+	void glDisableClientState(GLenum array);
+	void glDrawArrays(GLenum mode, GLint first, GLsizei count);
+	void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices);
+	void glEnable(GLenum cap);
+	void glEnableClientState(GLenum array);
+	void glFinish();
+	void glFlush();
+	void glFogx(GLenum pname, GLfixed param);
+	void glFogxv(GLenum pname, const GLfixed* params);
+	void glFrontFace(GLenum mode);
+	void glFrustumx(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar);
+	void glGetBooleanv(GLenum pname, GLboolean* params);
+	void glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params);
+	void glClipPlanex(GLenum pname, const GLfixed* eqn);
+	void glGenBuffers(GLsizei n, GLuint* buffers);
+	void glGenTextures(GLsizei n, GLuint* textures);
+	GLenum glGetError();
+	void glGetFixedv(GLenum pname, GLfixed* params);
+	void glGetIntegerv(GLenum pname, GLint* params);
+	void glGetLightxv(GLenum light, GLenum pname, GLfixed* params);
+	void glGetMaterialxv(GLenum face, GLenum pname, GLfixed* params);
+	void glGetPointerv(GLenum pname, GLvoid** params);
+	const GLubyte* glGetString(GLenum name);
+	void glGetTexEnviv(GLenum env, GLenum pname, GLint* params);
+	void glGetTexEnvxv(GLenum env, GLenum pname, GLfixed* params);
+	void glGetTexParameteriv(GLenum target, GLenum pname, GLint* params);
+	void glGetTexParameterxv(GLenum target, GLenum pname, GLfixed* params);
+	void glHint(GLenum target, GLenum mode);
+	GLboolean glIsBuffer(GLuint buffer);
+	GLboolean glIsEnabled(GLenum cap);
+	GLboolean glIsTexture(GLuint texture);
+	void glLightModelx(GLenum pname, GLfixed param);
+	void glLightModelxv(GLenum pname, const GLfixed* params);
+	void glLightx(GLenum light, GLenum pname, GLfixed param);
+	void glLightxv(GLenum light, GLenum pname, const GLfixed* params);
+	void glLineWidthx(GLfixed width);
+	void glLoadIdentity();
+	void glLoadMatrixx(const GLfixed* m);
+	void glLogicOp(GLenum opcode);
+	void glMaterialx(GLenum face, GLenum pname, GLfixed param);
+	void glMaterialxv(GLenum face, GLenum pname, const GLfixed* params);
+	void glMatrixMode(GLenum mode);
+	void glMultMatrixx(const GLfixed* m);
+	void glMultiTexCoord4x(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q);
+	void glNormal3x(GLfixed nx, GLfixed ny, GLfixed nz);
+	void glNormalPointer(GLenum type, GLsizei stride, const GLvoid* pointer);
+	void glOrthox(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar);
+	void glPixelStorei(GLenum pname, GLint param);
+	void glPointParameterx(GLenum pname, GLfixed param);
+	void glPointParameterxv(GLenum pname, const GLfixed* params);
+	void glPointSizex(GLfixed size);
+	void glPolygonOffsetx(GLfixed factor, GLfixed units);
+	void glPopMatrix();
+	void glPushMatrix();
+	void glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels);
+	void glRotatex(GLfixed angle, GLfixed x, GLfixed y, GLfixed z);
+	void glSampleCoverage(GLclampf value, GLboolean invert);
+	void glSampleCoveragex(GLclampx value, GLboolean invert);
+	void glScalex(GLfixed x, GLfixed y, GLfixed z);
+	void glScissor(GLint x, GLint y, GLsizei width, GLsizei height);
+	void glShadeModel(GLenum mode);
+	void glStencilFunc(GLenum func, GLint ref, GLuint mask);
+	void glStencilMask(GLuint mask);
+	void glStencilOp(GLenum fail, GLenum zfail, GLenum zpass);
+	void glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid* pointer);
+	void glTexEnvi(GLenum target, GLenum pname, GLint param);
+	void glTexEnvx(GLenum target, GLenum pname, GLfixed param);
+	void glTexEnviv(GLenum target, GLenum pname, const GLint* params);
+	void glTexEnvxv(GLenum target, GLenum pname, const GLfixed* params);
+	void glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels);
+	void glTexParameteri(GLenum target, GLenum pname, GLint param);
+	void glTexParameterx(GLenum target, GLenum pname, GLfixed param);
+	void glTexParameteriv(GLenum target, GLenum pname, const GLint* params);
+	void glTexParameterxv(GLenum target, GLenum pname, const GLfixed* params);
+	void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels);
+	void glTranslatex(GLfixed x, GLfixed y, GLfixed z);
+	void glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid* pointer);
+	void glViewport(GLint x, GLint y, GLsizei width, GLsizei height);
+	void glPointSizePointerOES(GLenum type, GLsizei stride, const GLvoid* pointer);
+	void glVertexPointerOffset(GLint size, GLenum type, GLsizei stride, GLuint offset);
+	void glColorPointerOffset(GLint size, GLenum type, GLsizei stride, GLuint offset);
+	void glNormalPointerOffset(GLenum type, GLsizei stride, GLuint offset);
+	void glPointSizePointerOffset(GLenum type, GLsizei stride, GLuint offset);
+	void glTexCoordPointerOffset(GLint size, GLenum type, GLsizei stride, GLuint offset);
+	void glWeightPointerOffset(GLint size, GLenum type, GLsizei stride, GLuint offset);
+	void glMatrixIndexPointerOffset(GLint size, GLenum type, GLsizei stride, GLuint offset);
+	void glVertexPointerData(GLint size, GLenum type, GLsizei stride, void* data, GLuint datalen);
+	void glColorPointerData(GLint size, GLenum type, GLsizei stride, void* data, GLuint datalen);
+	void glNormalPointerData(GLenum type, GLsizei stride, void* data, GLuint datalen);
+	void glTexCoordPointerData(GLint unit, GLint size, GLenum type, GLsizei stride, void* data, GLuint datalen);
+	void glPointSizePointerData(GLenum type, GLsizei stride, void* data, GLuint datalen);
+	void glWeightPointerData(GLint size, GLenum type, GLsizei stride, void* data, GLuint datalen);
+	void glMatrixIndexPointerData(GLint size, GLenum type, GLsizei stride, void* data, GLuint datalen);
+	void glDrawElementsOffset(GLenum mode, GLsizei count, GLenum type, GLuint offset);
+	void glDrawElementsData(GLenum mode, GLsizei count, GLenum type, void* data, GLuint datalen);
+	void glGetCompressedTextureFormats(int count, GLint* formats);
+	int glFinishRoundTrip();
+	void glBlendEquationSeparateOES(GLenum modeRGB, GLenum modeAlpha);
+	void glBlendFuncSeparateOES(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+	void glBlendEquationOES(GLenum mode);
+	void glDrawTexsOES(GLshort x, GLshort y, GLshort z, GLshort width, GLshort height);
+	void glDrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height);
+	void glDrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height);
+	void glDrawTexsvOES(const GLshort* coords);
+	void glDrawTexivOES(const GLint* coords);
+	void glDrawTexxvOES(const GLfixed* coords);
+	void glDrawTexfOES(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height);
+	void glDrawTexfvOES(const GLfloat* coords);
+	void glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image);
+	void glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image);
+	void glAlphaFuncxOES(GLenum func, GLclampx ref);
+	void glClearColorxOES(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha);
+	void glClearDepthxOES(GLclampx depth);
+	void glClipPlanexOES(GLenum plane, const GLfixed* equation);
+	void glClipPlanexIMG(GLenum plane, const GLfixed* equation);
+	void glColor4xOES(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha);
+	void glDepthRangexOES(GLclampx zNear, GLclampx zFar);
+	void glFogxOES(GLenum pname, GLfixed param);
+	void glFogxvOES(GLenum pname, const GLfixed* params);
+	void glFrustumxOES(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar);
+	void glGetClipPlanexOES(GLenum pname, GLfixed* eqn);
+	void glGetClipPlanex(GLenum pname, GLfixed* eqn);
+	void glGetFixedvOES(GLenum pname, GLfixed* params);
+	void glGetLightxvOES(GLenum light, GLenum pname, GLfixed* params);
+	void glGetMaterialxvOES(GLenum face, GLenum pname, GLfixed* params);
+	void glGetTexEnvxvOES(GLenum env, GLenum pname, GLfixed* params);
+	void glGetTexParameterxvOES(GLenum target, GLenum pname, GLfixed* params);
+	void glLightModelxOES(GLenum pname, GLfixed param);
+	void glLightModelxvOES(GLenum pname, const GLfixed* params);
+	void glLightxOES(GLenum light, GLenum pname, GLfixed param);
+	void glLightxvOES(GLenum light, GLenum pname, const GLfixed* params);
+	void glLineWidthxOES(GLfixed width);
+	void glLoadMatrixxOES(const GLfixed* m);
+	void glMaterialxOES(GLenum face, GLenum pname, GLfixed param);
+	void glMaterialxvOES(GLenum face, GLenum pname, const GLfixed* params);
+	void glMultMatrixxOES(const GLfixed* m);
+	void glMultiTexCoord4xOES(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q);
+	void glNormal3xOES(GLfixed nx, GLfixed ny, GLfixed nz);
+	void glOrthoxOES(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar);
+	void glPointParameterxOES(GLenum pname, GLfixed param);
+	void glPointParameterxvOES(GLenum pname, const GLfixed* params);
+	void glPointSizexOES(GLfixed size);
+	void glPolygonOffsetxOES(GLfixed factor, GLfixed units);
+	void glRotatexOES(GLfixed angle, GLfixed x, GLfixed y, GLfixed z);
+	void glSampleCoveragexOES(GLclampx value, GLboolean invert);
+	void glScalexOES(GLfixed x, GLfixed y, GLfixed z);
+	void glTexEnvxOES(GLenum target, GLenum pname, GLfixed param);
+	void glTexEnvxvOES(GLenum target, GLenum pname, const GLfixed* params);
+	void glTexParameterxOES(GLenum target, GLenum pname, GLfixed param);
+	void glTexParameterxvOES(GLenum target, GLenum pname, const GLfixed* params);
+	void glTranslatexOES(GLfixed x, GLfixed y, GLfixed z);
+	GLboolean glIsRenderbufferOES(GLuint renderbuffer);
+	void glBindRenderbufferOES(GLenum target, GLuint renderbuffer);
+	void glDeleteRenderbuffersOES(GLsizei n, const GLuint* renderbuffers);
+	void glGenRenderbuffersOES(GLsizei n, GLuint* renderbuffers);
+	void glRenderbufferStorageOES(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+	void glGetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint* params);
+	GLboolean glIsFramebufferOES(GLuint framebuffer);
+	void glBindFramebufferOES(GLenum target, GLuint framebuffer);
+	void glDeleteFramebuffersOES(GLsizei n, const GLuint* framebuffers);
+	void glGenFramebuffersOES(GLsizei n, GLuint* framebuffers);
+	GLenum glCheckFramebufferStatusOES(GLenum target);
+	void glFramebufferRenderbufferOES(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+	void glFramebufferTexture2DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+	void glGetFramebufferAttachmentParameterivOES(GLenum target, GLenum attachment, GLenum pname, GLint* params);
+	void glGenerateMipmapOES(GLenum target);
+	void* glMapBufferOES(GLenum target, GLenum access);
+	GLboolean glUnmapBufferOES(GLenum target);
+	void glGetBufferPointervOES(GLenum target, GLenum pname, GLvoid** params);
+	void glCurrentPaletteMatrixOES(GLuint matrixpaletteindex);
+	void glLoadPaletteFromModelViewMatrixOES();
+	void glMatrixIndexPointerOES(GLint size, GLenum type, GLsizei stride, const GLvoid* pointer);
+	void glWeightPointerOES(GLint size, GLenum type, GLsizei stride, const GLvoid* pointer);
+	GLbitfield glQueryMatrixxOES(GLfixed* mantissa, GLint* exponent);
+	void glDepthRangefOES(GLclampf zNear, GLclampf zFar);
+	void glFrustumfOES(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);
+	void glOrthofOES(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);
+	void glClipPlanefOES(GLenum plane, const GLfloat* equation);
+	void glClipPlanefIMG(GLenum plane, const GLfloat* equation);
+	void glGetClipPlanefOES(GLenum pname, GLfloat* eqn);
+	void glClearDepthfOES(GLclampf depth);
+	void glTexGenfOES(GLenum coord, GLenum pname, GLfloat param);
+	void glTexGenfvOES(GLenum coord, GLenum pname, const GLfloat* params);
+	void glTexGeniOES(GLenum coord, GLenum pname, GLint param);
+	void glTexGenivOES(GLenum coord, GLenum pname, const GLint* params);
+	void glTexGenxOES(GLenum coord, GLenum pname, GLfixed param);
+	void glTexGenxvOES(GLenum coord, GLenum pname, const GLfixed* params);
+	void glGetTexGenfvOES(GLenum coord, GLenum pname, GLfloat* params);
+	void glGetTexGenivOES(GLenum coord, GLenum pname, GLint* params);
+	void glGetTexGenxvOES(GLenum coord, GLenum pname, GLfixed* params);
+	void glBindVertexArrayOES(GLuint array);
+	void glDeleteVertexArraysOES(GLsizei n, const GLuint* arrays);
+	void glGenVertexArraysOES(GLsizei n, GLuint* arrays);
+	GLboolean glIsVertexArrayOES(GLuint array);
+	void glDiscardFramebufferEXT(GLenum target, GLsizei numAttachments, const GLenum* attachments);
+	void glMultiDrawArraysEXT(GLenum mode, GLint* first, GLsizei* count, GLsizei primcount);
+	void glMultiDrawElementsEXT(GLenum mode, const GLsizei* count, GLenum type, const GLvoid** indices, GLsizei primcount);
+	void glMultiDrawArraysSUN(GLenum mode, GLint* first, GLsizei* count, GLsizei primcount);
+	void glMultiDrawElementsSUN(GLenum mode, const GLsizei* count, GLenum type, const GLvoid** indices, GLsizei primcount);
+	void glRenderbufferStorageMultisampleIMG(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+	void glFramebufferTexture2DMultisampleIMG(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples);
+	void glDeleteFencesNV(GLsizei n, const GLuint* fences);
+	void glGenFencesNV(GLsizei n, GLuint* fences);
+	GLboolean glIsFenceNV(GLuint fence);
+	GLboolean glTestFenceNV(GLuint fence);
+	void glGetFenceivNV(GLuint fence, GLenum pname, GLint* params);
+	void glFinishFenceNV(GLuint fence);
+	void glSetFenceNV(GLuint fence, GLenum condition);
+	void glGetDriverControlsQCOM(GLint* num, GLsizei size, GLuint* driverControls);
+	void glGetDriverControlStringQCOM(GLuint driverControl, GLsizei bufSize, GLsizei* length, GLchar* driverControlString);
+	void glEnableDriverControlQCOM(GLuint driverControl);
+	void glDisableDriverControlQCOM(GLuint driverControl);
+	void glExtGetTexturesQCOM(GLuint* textures, GLint maxTextures, GLint* numTextures);
+	void glExtGetBuffersQCOM(GLuint* buffers, GLint maxBuffers, GLint* numBuffers);
+	void glExtGetRenderbuffersQCOM(GLuint* renderbuffers, GLint maxRenderbuffers, GLint* numRenderbuffers);
+	void glExtGetFramebuffersQCOM(GLuint* framebuffers, GLint maxFramebuffers, GLint* numFramebuffers);
+	void glExtGetTexLevelParameterivQCOM(GLuint texture, GLenum face, GLint level, GLenum pname, GLint* params);
+	void glExtTexObjectStateOverrideiQCOM(GLenum target, GLenum pname, GLint param);
+	void glExtGetTexSubImageQCOM(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid* texels);
+	void glExtGetBufferPointervQCOM(GLenum target, GLvoid** params);
+	void glExtGetShadersQCOM(GLuint* shaders, GLint maxShaders, GLint* numShaders);
+	void glExtGetProgramsQCOM(GLuint* programs, GLint maxPrograms, GLint* numPrograms);
+	GLboolean glExtIsProgramBinaryQCOM(GLuint program);
+	void glExtGetProgramBinarySourceQCOM(GLuint program, GLenum shadertype, GLchar* source, GLint* length);
+	void glStartTilingQCOM(GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask);
+	void glEndTilingQCOM(GLbitfield preserveMask);
+};
+
+#endif
+#ifndef GET_CONTEXT
+static gl_client_context_t::CONTEXT_ACCESSOR_TYPE *getCurrentContext = NULL;
+void gl_client_context_t::setContextAccessor(CONTEXT_ACCESSOR_TYPE *f) { getCurrentContext = f; }
+#define GET_CONTEXT gl_client_context_t * ctx = getCurrentContext() 
+#endif
+
+void glAlphaFunc(GLenum func, GLclampf ref)
+{
+	GET_CONTEXT; 
+	 ctx->glAlphaFunc(ctx, func, ref);
+}
+
+void glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+	GET_CONTEXT; 
+	 ctx->glClearColor(ctx, red, green, blue, alpha);
+}
+
+void glClearDepthf(GLclampf depth)
+{
+	GET_CONTEXT; 
+	 ctx->glClearDepthf(ctx, depth);
+}
+
+void glClipPlanef(GLenum plane, const GLfloat* equation)
+{
+	GET_CONTEXT; 
+	 ctx->glClipPlanef(ctx, plane, equation);
+}
+
+void glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+{
+	GET_CONTEXT; 
+	 ctx->glColor4f(ctx, red, green, blue, alpha);
+}
+
+void glDepthRangef(GLclampf zNear, GLclampf zFar)
+{
+	GET_CONTEXT; 
+	 ctx->glDepthRangef(ctx, zNear, zFar);
+}
+
+void glFogf(GLenum pname, GLfloat param)
+{
+	GET_CONTEXT; 
+	 ctx->glFogf(ctx, pname, param);
+}
+
+void glFogfv(GLenum pname, const GLfloat* params)
+{
+	GET_CONTEXT; 
+	 ctx->glFogfv(ctx, pname, params);
+}
+
+void glFrustumf(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
+{
+	GET_CONTEXT; 
+	 ctx->glFrustumf(ctx, left, right, bottom, top, zNear, zFar);
+}
+
+void glGetClipPlanef(GLenum pname, GLfloat* eqn)
+{
+	GET_CONTEXT; 
+	 ctx->glGetClipPlanef(ctx, pname, eqn);
+}
+
+void glGetFloatv(GLenum pname, GLfloat* params)
+{
+	GET_CONTEXT; 
+	 ctx->glGetFloatv(ctx, pname, params);
+}
+
+void glGetLightfv(GLenum light, GLenum pname, GLfloat* params)
+{
+	GET_CONTEXT; 
+	 ctx->glGetLightfv(ctx, light, pname, params);
+}
+
+void glGetMaterialfv(GLenum face, GLenum pname, GLfloat* params)
+{
+	GET_CONTEXT; 
+	 ctx->glGetMaterialfv(ctx, face, pname, params);
+}
+
+void glGetTexEnvfv(GLenum env, GLenum pname, GLfloat* params)
+{
+	GET_CONTEXT; 
+	 ctx->glGetTexEnvfv(ctx, env, pname, params);
+}
+
+void glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
+{
+	GET_CONTEXT; 
+	 ctx->glGetTexParameterfv(ctx, target, pname, params);
+}
+
+void glLightModelf(GLenum pname, GLfloat param)
+{
+	GET_CONTEXT; 
+	 ctx->glLightModelf(ctx, pname, param);
+}
+
+void glLightModelfv(GLenum pname, const GLfloat* params)
+{
+	GET_CONTEXT; 
+	 ctx->glLightModelfv(ctx, pname, params);
+}
+
+void glLightf(GLenum light, GLenum pname, GLfloat param)
+{
+	GET_CONTEXT; 
+	 ctx->glLightf(ctx, light, pname, param);
+}
+
+void glLightfv(GLenum light, GLenum pname, const GLfloat* params)
+{
+	GET_CONTEXT; 
+	 ctx->glLightfv(ctx, light, pname, params);
+}
+
+void glLineWidth(GLfloat width)
+{
+	GET_CONTEXT; 
+	 ctx->glLineWidth(ctx, width);
+}
+
+void glLoadMatrixf(const GLfloat* m)
+{
+	GET_CONTEXT; 
+	 ctx->glLoadMatrixf(ctx, m);
+}
+
+void glMaterialf(GLenum face, GLenum pname, GLfloat param)
+{
+	GET_CONTEXT; 
+	 ctx->glMaterialf(ctx, face, pname, param);
+}
+
+void glMaterialfv(GLenum face, GLenum pname, const GLfloat* params)
+{
+	GET_CONTEXT; 
+	 ctx->glMaterialfv(ctx, face, pname, params);
+}
+
+void glMultMatrixf(const GLfloat* m)
+{
+	GET_CONTEXT; 
+	 ctx->glMultMatrixf(ctx, m);
+}
+
+void glMultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
+{
+	GET_CONTEXT; 
+	 ctx->glMultiTexCoord4f(ctx, target, s, t, r, q);
+}
+
+void glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz)
+{
+	GET_CONTEXT; 
+	 ctx->glNormal3f(ctx, nx, ny, nz);
+}
+
+void glOrthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
+{
+	GET_CONTEXT; 
+	 ctx->glOrthof(ctx, left, right, bottom, top, zNear, zFar);
+}
+
+void glPointParameterf(GLenum pname, GLfloat param)
+{
+	GET_CONTEXT; 
+	 ctx->glPointParameterf(ctx, pname, param);
+}
+
+void glPointParameterfv(GLenum pname, const GLfloat* params)
+{
+	GET_CONTEXT; 
+	 ctx->glPointParameterfv(ctx, pname, params);
+}
+
+void glPointSize(GLfloat size)
+{
+	GET_CONTEXT; 
+	 ctx->glPointSize(ctx, size);
+}
+
+void glPolygonOffset(GLfloat factor, GLfloat units)
+{
+	GET_CONTEXT; 
+	 ctx->glPolygonOffset(ctx, factor, units);
+}
+
+void glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
+{
+	GET_CONTEXT; 
+	 ctx->glRotatef(ctx, angle, x, y, z);
+}
+
+void glScalef(GLfloat x, GLfloat y, GLfloat z)
+{
+	GET_CONTEXT; 
+	 ctx->glScalef(ctx, x, y, z);
+}
+
+void glTexEnvf(GLenum target, GLenum pname, GLfloat param)
+{
+	GET_CONTEXT; 
+	 ctx->glTexEnvf(ctx, target, pname, param);
+}
+
+void glTexEnvfv(GLenum target, GLenum pname, const GLfloat* params)
+{
+	GET_CONTEXT; 
+	 ctx->glTexEnvfv(ctx, target, pname, params);
+}
+
+void glTexParameterf(GLenum target, GLenum pname, GLfloat param)
+{
+	GET_CONTEXT; 
+	 ctx->glTexParameterf(ctx, target, pname, param);
+}
+
+void glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
+{
+	GET_CONTEXT; 
+	 ctx->glTexParameterfv(ctx, target, pname, params);
+}
+
+void glTranslatef(GLfloat x, GLfloat y, GLfloat z)
+{
+	GET_CONTEXT; 
+	 ctx->glTranslatef(ctx, x, y, z);
+}
+
+void glActiveTexture(GLenum texture)
+{
+	GET_CONTEXT; 
+	 ctx->glActiveTexture(ctx, texture);
+}
+
+void glAlphaFuncx(GLenum func, GLclampx ref)
+{
+	GET_CONTEXT; 
+	 ctx->glAlphaFuncx(ctx, func, ref);
+}
+
+void glBindBuffer(GLenum target, GLuint buffer)
+{
+	GET_CONTEXT; 
+	 ctx->glBindBuffer(ctx, target, buffer);
+}
+
+void glBindTexture(GLenum target, GLuint texture)
+{
+	GET_CONTEXT; 
+	 ctx->glBindTexture(ctx, target, texture);
+}
+
+void glBlendFunc(GLenum sfactor, GLenum dfactor)
+{
+	GET_CONTEXT; 
+	 ctx->glBlendFunc(ctx, sfactor, dfactor);
+}
+
+void glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
+{
+	GET_CONTEXT; 
+	 ctx->glBufferData(ctx, target, size, data, usage);
+}
+
+void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
+{
+	GET_CONTEXT; 
+	 ctx->glBufferSubData(ctx, target, offset, size, data);
+}
+
+void glClear(GLbitfield mask)
+{
+	GET_CONTEXT; 
+	 ctx->glClear(ctx, mask);
+}
+
+void glClearColorx(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha)
+{
+	GET_CONTEXT; 
+	 ctx->glClearColorx(ctx, red, green, blue, alpha);
+}
+
+void glClearDepthx(GLclampx depth)
+{
+	GET_CONTEXT; 
+	 ctx->glClearDepthx(ctx, depth);
+}
+
+void glClearStencil(GLint s)
+{
+	GET_CONTEXT; 
+	 ctx->glClearStencil(ctx, s);
+}
+
+void glClientActiveTexture(GLenum texture)
+{
+	GET_CONTEXT; 
+	 ctx->glClientActiveTexture(ctx, texture);
+}
+
+void glColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
+{
+	GET_CONTEXT; 
+	 ctx->glColor4ub(ctx, red, green, blue, alpha);
+}
+
+void glColor4x(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)
+{
+	GET_CONTEXT; 
+	 ctx->glColor4x(ctx, red, green, blue, alpha);
+}
+
+void glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
+{
+	GET_CONTEXT; 
+	 ctx->glColorMask(ctx, red, green, blue, alpha);
+}
+
+void glColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid* pointer)
+{
+	GET_CONTEXT; 
+	 ctx->glColorPointer(ctx, size, type, stride, pointer);
+}
+
+void glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data)
+{
+	GET_CONTEXT; 
+	 ctx->glCompressedTexImage2D(ctx, target, level, internalformat, width, height, border, imageSize, data);
+}
+
+void glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data)
+{
+	GET_CONTEXT; 
+	 ctx->glCompressedTexSubImage2D(ctx, target, level, xoffset, yoffset, width, height, format, imageSize, data);
+}
+
+void glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
+{
+	GET_CONTEXT; 
+	 ctx->glCopyTexImage2D(ctx, target, level, internalformat, x, y, width, height, border);
+}
+
+void glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+{
+	GET_CONTEXT; 
+	 ctx->glCopyTexSubImage2D(ctx, target, level, xoffset, yoffset, x, y, width, height);
+}
+
+void glCullFace(GLenum mode)
+{
+	GET_CONTEXT; 
+	 ctx->glCullFace(ctx, mode);
+}
+
+void glDeleteBuffers(GLsizei n, const GLuint* buffers)
+{
+	GET_CONTEXT; 
+	 if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
+	 ctx->glDeleteBuffers(ctx, n, buffers);
+}
+
+void glDeleteTextures(GLsizei n, const GLuint* textures)
+{
+	GET_CONTEXT; 
+	 if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
+	 ctx->glDeleteTextures(ctx, n, textures);
+}
+
+void glDepthFunc(GLenum func)
+{
+	GET_CONTEXT; 
+	 ctx->glDepthFunc(ctx, func);
+}
+
+void glDepthMask(GLboolean flag)
+{
+	GET_CONTEXT; 
+	 ctx->glDepthMask(ctx, flag);
+}
+
+void glDepthRangex(GLclampx zNear, GLclampx zFar)
+{
+	GET_CONTEXT; 
+	 ctx->glDepthRangex(ctx, zNear, zFar);
+}
+
+void glDisable(GLenum cap)
+{
+	GET_CONTEXT; 
+	 ctx->glDisable(ctx, cap);
+}
+
+void glDisableClientState(GLenum array)
+{
+	GET_CONTEXT; 
+	 ctx->glDisableClientState(ctx, array);
+}
+
+void glDrawArrays(GLenum mode, GLint first, GLsizei count)
+{
+	GET_CONTEXT; 
+	 ctx->glDrawArrays(ctx, mode, first, count);
+}
+
+void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
+{
+	GET_CONTEXT; 
+	 ctx->glDrawElements(ctx, mode, count, type, indices);
+}
+
+void glEnable(GLenum cap)
+{
+	GET_CONTEXT; 
+	 ctx->glEnable(ctx, cap);
+}
+
+void glEnableClientState(GLenum array)
+{
+	GET_CONTEXT; 
+	 ctx->glEnableClientState(ctx, array);
+}
+
+void glFinish()
+{
+	GET_CONTEXT; 
+	 ctx->glFinish(ctx);
+}
+
+void glFlush()
+{
+	GET_CONTEXT; 
+	 ctx->glFlush(ctx);
+}
+
+void glFogx(GLenum pname, GLfixed param)
+{
+	GET_CONTEXT; 
+	 ctx->glFogx(ctx, pname, param);
+}
+
+void glFogxv(GLenum pname, const GLfixed* params)
+{
+	GET_CONTEXT; 
+	 ctx->glFogxv(ctx, pname, params);
+}
+
+void glFrontFace(GLenum mode)
+{
+	GET_CONTEXT; 
+	 ctx->glFrontFace(ctx, mode);
+}
+
+void glFrustumx(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
+{
+	GET_CONTEXT; 
+	 ctx->glFrustumx(ctx, left, right, bottom, top, zNear, zFar);
+}
+
+void glGetBooleanv(GLenum pname, GLboolean* params)
+{
+	GET_CONTEXT; 
+	 ctx->glGetBooleanv(ctx, pname, params);
+}
+
+void glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+	GET_CONTEXT; 
+	 ctx->glGetBufferParameteriv(ctx, target, pname, params);
+}
+
+void glClipPlanex(GLenum pname, const GLfixed* eqn)
+{
+	GET_CONTEXT; 
+	 ctx->glClipPlanex(ctx, pname, eqn);
+}
+
+void glGenBuffers(GLsizei n, GLuint* buffers)
+{
+	GET_CONTEXT; 
+	 if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
+	 ctx->glGenBuffers(ctx, n, buffers);
+}
+
+void glGenTextures(GLsizei n, GLuint* textures)
+{
+	GET_CONTEXT; 
+	 if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
+	 ctx->glGenTextures(ctx, n, textures);
+}
+
+GLenum glGetError()
+{
+	GET_CONTEXT; 
+	 return ctx->glGetError(ctx);
+}
+
+void glGetFixedv(GLenum pname, GLfixed* params)
+{
+	GET_CONTEXT; 
+	 ctx->glGetFixedv(ctx, pname, params);
+}
+
+void glGetIntegerv(GLenum pname, GLint* params)
+{
+	GET_CONTEXT; 
+	 ctx->glGetIntegerv(ctx, pname, params);
+}
+
+void glGetLightxv(GLenum light, GLenum pname, GLfixed* params)
+{
+	GET_CONTEXT; 
+	 ctx->glGetLightxv(ctx, light, pname, params);
+}
+
+void glGetMaterialxv(GLenum face, GLenum pname, GLfixed* params)
+{
+	GET_CONTEXT; 
+	 ctx->glGetMaterialxv(ctx, face, pname, params);
+}
+
+void glGetPointerv(GLenum pname, GLvoid** params)
+{
+	GET_CONTEXT; 
+	 ctx->glGetPointerv(ctx, pname, params);
+}
+
+const GLubyte* glGetString(GLenum name)
+{
+	GET_CONTEXT; 
+	 return ctx->glGetString(ctx, name);
+}
+
+void glGetTexEnviv(GLenum env, GLenum pname, GLint* params)
+{
+	GET_CONTEXT; 
+	 ctx->glGetTexEnviv(ctx, env, pname, params);
+}
+
+void glGetTexEnvxv(GLenum env, GLenum pname, GLfixed* params)
+{
+	GET_CONTEXT; 
+	 ctx->glGetTexEnvxv(ctx, env, pname, params);
+}
+
+void glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+	GET_CONTEXT; 
+	 ctx->glGetTexParameteriv(ctx, target, pname, params);
+}
+
+void glGetTexParameterxv(GLenum target, GLenum pname, GLfixed* params)
+{
+	GET_CONTEXT; 
+	 ctx->glGetTexParameterxv(ctx, target, pname, params);
+}
+
+void glHint(GLenum target, GLenum mode)
+{
+	GET_CONTEXT; 
+	 ctx->glHint(ctx, target, mode);
+}
+
+GLboolean glIsBuffer(GLuint buffer)
+{
+	GET_CONTEXT; 
+	 return ctx->glIsBuffer(ctx, buffer);
+}
+
+GLboolean glIsEnabled(GLenum cap)
+{
+	GET_CONTEXT; 
+	 return ctx->glIsEnabled(ctx, cap);
+}
+
+GLboolean glIsTexture(GLuint texture)
+{
+	GET_CONTEXT; 
+	 return ctx->glIsTexture(ctx, texture);
+}
+
+void glLightModelx(GLenum pname, GLfixed param)
+{
+	GET_CONTEXT; 
+	 ctx->glLightModelx(ctx, pname, param);
+}
+
+void glLightModelxv(GLenum pname, const GLfixed* params)
+{
+	GET_CONTEXT; 
+	 ctx->glLightModelxv(ctx, pname, params);
+}
+
+void glLightx(GLenum light, GLenum pname, GLfixed param)
+{
+	GET_CONTEXT; 
+	 ctx->glLightx(ctx, light, pname, param);
+}
+
+void glLightxv(GLenum light, GLenum pname, const GLfixed* params)
+{
+	GET_CONTEXT; 
+	 ctx->glLightxv(ctx, light, pname, params);
+}
+
+void glLineWidthx(GLfixed width)
+{
+	GET_CONTEXT; 
+	 ctx->glLineWidthx(ctx, width);
+}
+
+void glLoadIdentity()
+{
+	GET_CONTEXT; 
+	 ctx->glLoadIdentity(ctx);
+}
+
+void glLoadMatrixx(const GLfixed* m)
+{
+	GET_CONTEXT; 
+	 ctx->glLoadMatrixx(ctx, m);
+}
+
+void glLogicOp(GLenum opcode)
+{
+	GET_CONTEXT; 
+	 ctx->glLogicOp(ctx, opcode);
+}
+
+void glMaterialx(GLenum face, GLenum pname, GLfixed param)
+{
+	GET_CONTEXT; 
+	 ctx->glMaterialx(ctx, face, pname, param);
+}
+
+void glMaterialxv(GLenum face, GLenum pname, const GLfixed* params)
+{
+	GET_CONTEXT; 
+	 ctx->glMaterialxv(ctx, face, pname, params);
+}
+
+void glMatrixMode(GLenum mode)
+{
+	GET_CONTEXT; 
+	 ctx->glMatrixMode(ctx, mode);
+}
+
+void glMultMatrixx(const GLfixed* m)
+{
+	GET_CONTEXT; 
+	 ctx->glMultMatrixx(ctx, m);
+}
+
+void glMultiTexCoord4x(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q)
+{
+	GET_CONTEXT; 
+	 ctx->glMultiTexCoord4x(ctx, target, s, t, r, q);
+}
+
+void glNormal3x(GLfixed nx, GLfixed ny, GLfixed nz)
+{
+	GET_CONTEXT; 
+	 ctx->glNormal3x(ctx, nx, ny, nz);
+}
+
+void glNormalPointer(GLenum type, GLsizei stride, const GLvoid* pointer)
+{
+	GET_CONTEXT; 
+	 ctx->glNormalPointer(ctx, type, stride, pointer);
+}
+
+void glOrthox(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
+{
+	GET_CONTEXT; 
+	 ctx->glOrthox(ctx, left, right, bottom, top, zNear, zFar);
+}
+
+void glPixelStorei(GLenum pname, GLint param)
+{
+	GET_CONTEXT; 
+	 ctx->glPixelStorei(ctx, pname, param);
+}
+
+void glPointParameterx(GLenum pname, GLfixed param)
+{
+	GET_CONTEXT; 
+	 ctx->glPointParameterx(ctx, pname, param);
+}
+
+void glPointParameterxv(GLenum pname, const GLfixed* params)
+{
+	GET_CONTEXT; 
+	 ctx->glPointParameterxv(ctx, pname, params);
+}
+
+void glPointSizex(GLfixed size)
+{
+	GET_CONTEXT; 
+	 ctx->glPointSizex(ctx, size);
+}
+
+void glPolygonOffsetx(GLfixed factor, GLfixed units)
+{
+	GET_CONTEXT; 
+	 ctx->glPolygonOffsetx(ctx, factor, units);
+}
+
+void glPopMatrix()
+{
+	GET_CONTEXT; 
+	 ctx->glPopMatrix(ctx);
+}
+
+void glPushMatrix()
+{
+	GET_CONTEXT; 
+	 ctx->glPushMatrix(ctx);
+}
+
+void glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
+{
+	GET_CONTEXT; 
+	 ctx->glReadPixels(ctx, x, y, width, height, format, type, pixels);
+}
+
+void glRotatex(GLfixed angle, GLfixed x, GLfixed y, GLfixed z)
+{
+	GET_CONTEXT; 
+	 ctx->glRotatex(ctx, angle, x, y, z);
+}
+
+void glSampleCoverage(GLclampf value, GLboolean invert)
+{
+	GET_CONTEXT; 
+	 ctx->glSampleCoverage(ctx, value, invert);
+}
+
+void glSampleCoveragex(GLclampx value, GLboolean invert)
+{
+	GET_CONTEXT; 
+	 ctx->glSampleCoveragex(ctx, value, invert);
+}
+
+void glScalex(GLfixed x, GLfixed y, GLfixed z)
+{
+	GET_CONTEXT; 
+	 ctx->glScalex(ctx, x, y, z);
+}
+
+void glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+	GET_CONTEXT; 
+	 ctx->glScissor(ctx, x, y, width, height);
+}
+
+void glShadeModel(GLenum mode)
+{
+	GET_CONTEXT; 
+	 ctx->glShadeModel(ctx, mode);
+}
+
+void glStencilFunc(GLenum func, GLint ref, GLuint mask)
+{
+	GET_CONTEXT; 
+	 ctx->glStencilFunc(ctx, func, ref, mask);
+}
+
+void glStencilMask(GLuint mask)
+{
+	GET_CONTEXT; 
+	 ctx->glStencilMask(ctx, mask);
+}
+
+void glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
+{
+	GET_CONTEXT; 
+	 ctx->glStencilOp(ctx, fail, zfail, zpass);
+}
+
+void glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid* pointer)
+{
+	GET_CONTEXT; 
+	 ctx->glTexCoordPointer(ctx, size, type, stride, pointer);
+}
+
+void glTexEnvi(GLenum target, GLenum pname, GLint param)
+{
+	GET_CONTEXT; 
+	 ctx->glTexEnvi(ctx, target, pname, param);
+}
+
+void glTexEnvx(GLenum target, GLenum pname, GLfixed param)
+{
+	GET_CONTEXT; 
+	 ctx->glTexEnvx(ctx, target, pname, param);
+}
+
+void glTexEnviv(GLenum target, GLenum pname, const GLint* params)
+{
+	GET_CONTEXT; 
+	 ctx->glTexEnviv(ctx, target, pname, params);
+}
+
+void glTexEnvxv(GLenum target, GLenum pname, const GLfixed* params)
+{
+	GET_CONTEXT; 
+	 ctx->glTexEnvxv(ctx, target, pname, params);
+}
+
+void glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels)
+{
+	GET_CONTEXT; 
+	 ctx->glTexImage2D(ctx, target, level, internalformat, width, height, border, format, type, pixels);
+}
+
+void glTexParameteri(GLenum target, GLenum pname, GLint param)
+{
+	GET_CONTEXT; 
+	 ctx->glTexParameteri(ctx, target, pname, param);
+}
+
+void glTexParameterx(GLenum target, GLenum pname, GLfixed param)
+{
+	GET_CONTEXT; 
+	 ctx->glTexParameterx(ctx, target, pname, param);
+}
+
+void glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
+{
+	GET_CONTEXT; 
+	 ctx->glTexParameteriv(ctx, target, pname, params);
+}
+
+void glTexParameterxv(GLenum target, GLenum pname, const GLfixed* params)
+{
+	GET_CONTEXT; 
+	 ctx->glTexParameterxv(ctx, target, pname, params);
+}
+
+void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels)
+{
+	GET_CONTEXT; 
+	 ctx->glTexSubImage2D(ctx, target, level, xoffset, yoffset, width, height, format, type, pixels);
+}
+
+void glTranslatex(GLfixed x, GLfixed y, GLfixed z)
+{
+	GET_CONTEXT; 
+	 ctx->glTranslatex(ctx, x, y, z);
+}
+
+void glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid* pointer)
+{
+	GET_CONTEXT; 
+	 ctx->glVertexPointer(ctx, size, type, stride, pointer);
+}
+
+void glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+	GET_CONTEXT; 
+	 ctx->glViewport(ctx, x, y, width, height);
+}
+
+void glPointSizePointerOES(GLenum type, GLsizei stride, const GLvoid* pointer)
+{
+	GET_CONTEXT; 
+	 ctx->glPointSizePointerOES(ctx, type, stride, pointer);
+}
+
+void glVertexPointerOffset(GLint size, GLenum type, GLsizei stride, GLuint offset)
+{
+	GET_CONTEXT; 
+	 ctx->glVertexPointerOffset(ctx, size, type, stride, offset);
+}
+
+void glColorPointerOffset(GLint size, GLenum type, GLsizei stride, GLuint offset)
+{
+	GET_CONTEXT; 
+	 ctx->glColorPointerOffset(ctx, size, type, stride, offset);
+}
+
+void glNormalPointerOffset(GLenum type, GLsizei stride, GLuint offset)
+{
+	GET_CONTEXT; 
+	 ctx->glNormalPointerOffset(ctx, type, stride, offset);
+}
+
+void glPointSizePointerOffset(GLenum type, GLsizei stride, GLuint offset)
+{
+	GET_CONTEXT; 
+	 ctx->glPointSizePointerOffset(ctx, type, stride, offset);
+}
+
+void glTexCoordPointerOffset(GLint size, GLenum type, GLsizei stride, GLuint offset)
+{
+	GET_CONTEXT; 
+	 ctx->glTexCoordPointerOffset(ctx, size, type, stride, offset);
+}
+
+void glWeightPointerOffset(GLint size, GLenum type, GLsizei stride, GLuint offset)
+{
+	GET_CONTEXT; 
+	 ctx->glWeightPointerOffset(ctx, size, type, stride, offset);
+}
+
+void glMatrixIndexPointerOffset(GLint size, GLenum type, GLsizei stride, GLuint offset)
+{
+	GET_CONTEXT; 
+	 ctx->glMatrixIndexPointerOffset(ctx, size, type, stride, offset);
+}
+
+void glVertexPointerData(GLint size, GLenum type, GLsizei stride, void* data, GLuint datalen)
+{
+	GET_CONTEXT; 
+	 ctx->glVertexPointerData(ctx, size, type, stride, data, datalen);
+}
+
+void glColorPointerData(GLint size, GLenum type, GLsizei stride, void* data, GLuint datalen)
+{
+	GET_CONTEXT; 
+	 ctx->glColorPointerData(ctx, size, type, stride, data, datalen);
+}
+
+void glNormalPointerData(GLenum type, GLsizei stride, void* data, GLuint datalen)
+{
+	GET_CONTEXT; 
+	 ctx->glNormalPointerData(ctx, type, stride, data, datalen);
+}
+
+void glTexCoordPointerData(GLint unit, GLint size, GLenum type, GLsizei stride, void* data, GLuint datalen)
+{
+	GET_CONTEXT; 
+	 ctx->glTexCoordPointerData(ctx, unit, size, type, stride, data, datalen);
+}
+
+void glPointSizePointerData(GLenum type, GLsizei stride, void* data, GLuint datalen)
+{
+	GET_CONTEXT; 
+	 ctx->glPointSizePointerData(ctx, type, stride, data, datalen);
+}
+
+void glWeightPointerData(GLint size, GLenum type, GLsizei stride, void* data, GLuint datalen)
+{
+	GET_CONTEXT; 
+	 ctx->glWeightPointerData(ctx, size, type, stride, data, datalen);
+}
+
+void glMatrixIndexPointerData(GLint size, GLenum type, GLsizei stride, void* data, GLuint datalen)
+{
+	GET_CONTEXT; 
+	 ctx->glMatrixIndexPointerData(ctx, size, type, stride, data, datalen);
+}
+
+void glDrawElementsOffset(GLenum mode, GLsizei count, GLenum type, GLuint offset)
+{
+	GET_CONTEXT; 
+	 ctx->glDrawElementsOffset(ctx, mode, count, type, offset);
+}
+
+void glDrawElementsData(GLenum mode, GLsizei count, GLenum type, void* data, GLuint datalen)
+{
+	GET_CONTEXT; 
+	 ctx->glDrawElementsData(ctx, mode, count, type, data, datalen);
+}
+
+void glGetCompressedTextureFormats(int count, GLint* formats)
+{
+	GET_CONTEXT; 
+	 ctx->glGetCompressedTextureFormats(ctx, count, formats);
+}
+
+int glFinishRoundTrip()
+{
+	GET_CONTEXT; 
+	 return ctx->glFinishRoundTrip(ctx);
+}
+
+void glBlendEquationSeparateOES(GLenum modeRGB, GLenum modeAlpha)
+{
+	GET_CONTEXT; 
+	 ctx->glBlendEquationSeparateOES(ctx, modeRGB, modeAlpha);
+}
+
+void glBlendFuncSeparateOES(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+{
+	GET_CONTEXT; 
+	 ctx->glBlendFuncSeparateOES(ctx, srcRGB, dstRGB, srcAlpha, dstAlpha);
+}
+
+void glBlendEquationOES(GLenum mode)
+{
+	GET_CONTEXT; 
+	 ctx->glBlendEquationOES(ctx, mode);
+}
+
+void glDrawTexsOES(GLshort x, GLshort y, GLshort z, GLshort width, GLshort height)
+{
+	GET_CONTEXT; 
+	 ctx->glDrawTexsOES(ctx, x, y, z, width, height);
+}
+
+void glDrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height)
+{
+	GET_CONTEXT; 
+	 ctx->glDrawTexiOES(ctx, x, y, z, width, height);
+}
+
+void glDrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height)
+{
+	GET_CONTEXT; 
+	 ctx->glDrawTexxOES(ctx, x, y, z, width, height);
+}
+
+void glDrawTexsvOES(const GLshort* coords)
+{
+	GET_CONTEXT; 
+	 ctx->glDrawTexsvOES(ctx, coords);
+}
+
+void glDrawTexivOES(const GLint* coords)
+{
+	GET_CONTEXT; 
+	 ctx->glDrawTexivOES(ctx, coords);
+}
+
+void glDrawTexxvOES(const GLfixed* coords)
+{
+	GET_CONTEXT; 
+	 ctx->glDrawTexxvOES(ctx, coords);
+}
+
+void glDrawTexfOES(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height)
+{
+	GET_CONTEXT; 
+	 ctx->glDrawTexfOES(ctx, x, y, z, width, height);
+}
+
+void glDrawTexfvOES(const GLfloat* coords)
+{
+	GET_CONTEXT; 
+	 ctx->glDrawTexfvOES(ctx, coords);
+}
+
+void glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
+{
+	GET_CONTEXT; 
+	 ctx->glEGLImageTargetTexture2DOES(ctx, target, image);
+}
+
+void glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
+{
+	GET_CONTEXT; 
+	 ctx->glEGLImageTargetRenderbufferStorageOES(ctx, target, image);
+}
+
+void glAlphaFuncxOES(GLenum func, GLclampx ref)
+{
+	GET_CONTEXT; 
+	 ctx->glAlphaFuncxOES(ctx, func, ref);
+}
+
+void glClearColorxOES(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha)
+{
+	GET_CONTEXT; 
+	 ctx->glClearColorxOES(ctx, red, green, blue, alpha);
+}
+
+void glClearDepthxOES(GLclampx depth)
+{
+	GET_CONTEXT; 
+	 ctx->glClearDepthxOES(ctx, depth);
+}
+
+void glClipPlanexOES(GLenum plane, const GLfixed* equation)
+{
+	GET_CONTEXT; 
+	 ctx->glClipPlanexOES(ctx, plane, equation);
+}
+
+void glClipPlanexIMG(GLenum plane, const GLfixed* equation)
+{
+	GET_CONTEXT; 
+	 ctx->glClipPlanexIMG(ctx, plane, equation);
+}
+
+void glColor4xOES(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)
+{
+	GET_CONTEXT; 
+	 ctx->glColor4xOES(ctx, red, green, blue, alpha);
+}
+
+void glDepthRangexOES(GLclampx zNear, GLclampx zFar)
+{
+	GET_CONTEXT; 
+	 ctx->glDepthRangexOES(ctx, zNear, zFar);
+}
+
+void glFogxOES(GLenum pname, GLfixed param)
+{
+	GET_CONTEXT; 
+	 ctx->glFogxOES(ctx, pname, param);
+}
+
+void glFogxvOES(GLenum pname, const GLfixed* params)
+{
+	GET_CONTEXT; 
+	 ctx->glFogxvOES(ctx, pname, params);
+}
+
+void glFrustumxOES(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
+{
+	GET_CONTEXT; 
+	 ctx->glFrustumxOES(ctx, left, right, bottom, top, zNear, zFar);
+}
+
+void glGetClipPlanexOES(GLenum pname, GLfixed* eqn)
+{
+	GET_CONTEXT; 
+	 ctx->glGetClipPlanexOES(ctx, pname, eqn);
+}
+
+void glGetClipPlanex(GLenum pname, GLfixed* eqn)
+{
+	GET_CONTEXT; 
+	 ctx->glGetClipPlanex(ctx, pname, eqn);
+}
+
+void glGetFixedvOES(GLenum pname, GLfixed* params)
+{
+	GET_CONTEXT; 
+	 ctx->glGetFixedvOES(ctx, pname, params);
+}
+
+void glGetLightxvOES(GLenum light, GLenum pname, GLfixed* params)
+{
+	GET_CONTEXT; 
+	 ctx->glGetLightxvOES(ctx, light, pname, params);
+}
+
+void glGetMaterialxvOES(GLenum face, GLenum pname, GLfixed* params)
+{
+	GET_CONTEXT; 
+	 ctx->glGetMaterialxvOES(ctx, face, pname, params);
+}
+
+void glGetTexEnvxvOES(GLenum env, GLenum pname, GLfixed* params)
+{
+	GET_CONTEXT; 
+	 ctx->glGetTexEnvxvOES(ctx, env, pname, params);
+}
+
+void glGetTexParameterxvOES(GLenum target, GLenum pname, GLfixed* params)
+{
+	GET_CONTEXT; 
+	 ctx->glGetTexParameterxvOES(ctx, target, pname, params);
+}
+
+void glLightModelxOES(GLenum pname, GLfixed param)
+{
+	GET_CONTEXT; 
+	 ctx->glLightModelxOES(ctx, pname, param);
+}
+
+void glLightModelxvOES(GLenum pname, const GLfixed* params)
+{
+	GET_CONTEXT; 
+	 ctx->glLightModelxvOES(ctx, pname, params);
+}
+
+void glLightxOES(GLenum light, GLenum pname, GLfixed param)
+{
+	GET_CONTEXT; 
+	 ctx->glLightxOES(ctx, light, pname, param);
+}
+
+void glLightxvOES(GLenum light, GLenum pname, const GLfixed* params)
+{
+	GET_CONTEXT; 
+	 ctx->glLightxvOES(ctx, light, pname, params);
+}
+
+void glLineWidthxOES(GLfixed width)
+{
+	GET_CONTEXT; 
+	 ctx->glLineWidthxOES(ctx, width);
+}
+
+void glLoadMatrixxOES(const GLfixed* m)
+{
+	GET_CONTEXT; 
+	 ctx->glLoadMatrixxOES(ctx, m);
+}
+
+void glMaterialxOES(GLenum face, GLenum pname, GLfixed param)
+{
+	GET_CONTEXT; 
+	 ctx->glMaterialxOES(ctx, face, pname, param);
+}
+
+void glMaterialxvOES(GLenum face, GLenum pname, const GLfixed* params)
+{
+	GET_CONTEXT; 
+	 ctx->glMaterialxvOES(ctx, face, pname, params);
+}
+
+void glMultMatrixxOES(const GLfixed* m)
+{
+	GET_CONTEXT; 
+	 ctx->glMultMatrixxOES(ctx, m);
+}
+
+void glMultiTexCoord4xOES(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q)
+{
+	GET_CONTEXT; 
+	 ctx->glMultiTexCoord4xOES(ctx, target, s, t, r, q);
+}
+
+void glNormal3xOES(GLfixed nx, GLfixed ny, GLfixed nz)
+{
+	GET_CONTEXT; 
+	 ctx->glNormal3xOES(ctx, nx, ny, nz);
+}
+
+void glOrthoxOES(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
+{
+	GET_CONTEXT; 
+	 ctx->glOrthoxOES(ctx, left, right, bottom, top, zNear, zFar);
+}
+
+void glPointParameterxOES(GLenum pname, GLfixed param)
+{
+	GET_CONTEXT; 
+	 ctx->glPointParameterxOES(ctx, pname, param);
+}
+
+void glPointParameterxvOES(GLenum pname, const GLfixed* params)
+{
+	GET_CONTEXT; 
+	 ctx->glPointParameterxvOES(ctx, pname, params);
+}
+
+void glPointSizexOES(GLfixed size)
+{
+	GET_CONTEXT; 
+	 ctx->glPointSizexOES(ctx, size);
+}
+
+void glPolygonOffsetxOES(GLfixed factor, GLfixed units)
+{
+	GET_CONTEXT; 
+	 ctx->glPolygonOffsetxOES(ctx, factor, units);
+}
+
+void glRotatexOES(GLfixed angle, GLfixed x, GLfixed y, GLfixed z)
+{
+	GET_CONTEXT; 
+	 ctx->glRotatexOES(ctx, angle, x, y, z);
+}
+
+void glSampleCoveragexOES(GLclampx value, GLboolean invert)
+{
+	GET_CONTEXT; 
+	 ctx->glSampleCoveragexOES(ctx, value, invert);
+}
+
+void glScalexOES(GLfixed x, GLfixed y, GLfixed z)
+{
+	GET_CONTEXT; 
+	 ctx->glScalexOES(ctx, x, y, z);
+}
+
+void glTexEnvxOES(GLenum target, GLenum pname, GLfixed param)
+{
+	GET_CONTEXT; 
+	 ctx->glTexEnvxOES(ctx, target, pname, param);
+}
+
+void glTexEnvxvOES(GLenum target, GLenum pname, const GLfixed* params)
+{
+	GET_CONTEXT; 
+	 ctx->glTexEnvxvOES(ctx, target, pname, params);
+}
+
+void glTexParameterxOES(GLenum target, GLenum pname, GLfixed param)
+{
+	GET_CONTEXT; 
+	 ctx->glTexParameterxOES(ctx, target, pname, param);
+}
+
+void glTexParameterxvOES(GLenum target, GLenum pname, const GLfixed* params)
+{
+	GET_CONTEXT; 
+	 ctx->glTexParameterxvOES(ctx, target, pname, params);
+}
+
+void glTranslatexOES(GLfixed x, GLfixed y, GLfixed z)
+{
+	GET_CONTEXT; 
+	 ctx->glTranslatexOES(ctx, x, y, z);
+}
+
+GLboolean glIsRenderbufferOES(GLuint renderbuffer)
+{
+	GET_CONTEXT; 
+	 return ctx->glIsRenderbufferOES(ctx, renderbuffer);
+}
+
+void glBindRenderbufferOES(GLenum target, GLuint renderbuffer)
+{
+	GET_CONTEXT; 
+	 ctx->glBindRenderbufferOES(ctx, target, renderbuffer);
+}
+
+void glDeleteRenderbuffersOES(GLsizei n, const GLuint* renderbuffers)
+{
+	GET_CONTEXT; 
+	 if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
+	 ctx->glDeleteRenderbuffersOES(ctx, n, renderbuffers);
+}
+
+void glGenRenderbuffersOES(GLsizei n, GLuint* renderbuffers)
+{
+	GET_CONTEXT; 
+	 if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
+	 ctx->glGenRenderbuffersOES(ctx, n, renderbuffers);
+}
+
+void glRenderbufferStorageOES(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+{
+	GET_CONTEXT; 
+	 ctx->glRenderbufferStorageOES(ctx, target, internalformat, width, height);
+}
+
+void glGetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint* params)
+{
+	GET_CONTEXT; 
+	 ctx->glGetRenderbufferParameterivOES(ctx, target, pname, params);
+}
+
+GLboolean glIsFramebufferOES(GLuint framebuffer)
+{
+	GET_CONTEXT; 
+	 return ctx->glIsFramebufferOES(ctx, framebuffer);
+}
+
+void glBindFramebufferOES(GLenum target, GLuint framebuffer)
+{
+	GET_CONTEXT; 
+	 ctx->glBindFramebufferOES(ctx, target, framebuffer);
+}
+
+void glDeleteFramebuffersOES(GLsizei n, const GLuint* framebuffers)
+{
+	GET_CONTEXT; 
+	 if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
+	 ctx->glDeleteFramebuffersOES(ctx, n, framebuffers);
+}
+
+void glGenFramebuffersOES(GLsizei n, GLuint* framebuffers)
+{
+	GET_CONTEXT; 
+	 if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
+	 ctx->glGenFramebuffersOES(ctx, n, framebuffers);
+}
+
+GLenum glCheckFramebufferStatusOES(GLenum target)
+{
+	GET_CONTEXT; 
+	 return ctx->glCheckFramebufferStatusOES(ctx, target);
+}
+
+void glFramebufferRenderbufferOES(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
+{
+	GET_CONTEXT; 
+	 ctx->glFramebufferRenderbufferOES(ctx, target, attachment, renderbuffertarget, renderbuffer);
+}
+
+void glFramebufferTexture2DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
+{
+	GET_CONTEXT; 
+	 ctx->glFramebufferTexture2DOES(ctx, target, attachment, textarget, texture, level);
+}
+
+void glGetFramebufferAttachmentParameterivOES(GLenum target, GLenum attachment, GLenum pname, GLint* params)
+{
+	GET_CONTEXT; 
+	 ctx->glGetFramebufferAttachmentParameterivOES(ctx, target, attachment, pname, params);
+}
+
+void glGenerateMipmapOES(GLenum target)
+{
+	GET_CONTEXT; 
+	 ctx->glGenerateMipmapOES(ctx, target);
+}
+
+void* glMapBufferOES(GLenum target, GLenum access)
+{
+	GET_CONTEXT; 
+	 return ctx->glMapBufferOES(ctx, target, access);
+}
+
+GLboolean glUnmapBufferOES(GLenum target)
+{
+	GET_CONTEXT; 
+	 return ctx->glUnmapBufferOES(ctx, target);
+}
+
+void glGetBufferPointervOES(GLenum target, GLenum pname, GLvoid** params)
+{
+	GET_CONTEXT; 
+	 ctx->glGetBufferPointervOES(ctx, target, pname, params);
+}
+
+void glCurrentPaletteMatrixOES(GLuint matrixpaletteindex)
+{
+	GET_CONTEXT; 
+	 ctx->glCurrentPaletteMatrixOES(ctx, matrixpaletteindex);
+}
+
+void glLoadPaletteFromModelViewMatrixOES()
+{
+	GET_CONTEXT; 
+	 ctx->glLoadPaletteFromModelViewMatrixOES(ctx);
+}
+
+void glMatrixIndexPointerOES(GLint size, GLenum type, GLsizei stride, const GLvoid* pointer)
+{
+	GET_CONTEXT; 
+	 ctx->glMatrixIndexPointerOES(ctx, size, type, stride, pointer);
+}
+
+void glWeightPointerOES(GLint size, GLenum type, GLsizei stride, const GLvoid* pointer)
+{
+	GET_CONTEXT; 
+	 ctx->glWeightPointerOES(ctx, size, type, stride, pointer);
+}
+
+GLbitfield glQueryMatrixxOES(GLfixed* mantissa, GLint* exponent)
+{
+	GET_CONTEXT; 
+	 return ctx->glQueryMatrixxOES(ctx, mantissa, exponent);
+}
+
+void glDepthRangefOES(GLclampf zNear, GLclampf zFar)
+{
+	GET_CONTEXT; 
+	 ctx->glDepthRangefOES(ctx, zNear, zFar);
+}
+
+void glFrustumfOES(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
+{
+	GET_CONTEXT; 
+	 ctx->glFrustumfOES(ctx, left, right, bottom, top, zNear, zFar);
+}
+
+void glOrthofOES(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
+{
+	GET_CONTEXT; 
+	 ctx->glOrthofOES(ctx, left, right, bottom, top, zNear, zFar);
+}
+
+void glClipPlanefOES(GLenum plane, const GLfloat* equation)
+{
+	GET_CONTEXT; 
+	 ctx->glClipPlanefOES(ctx, plane, equation);
+}
+
+void glClipPlanefIMG(GLenum plane, const GLfloat* equation)
+{
+	GET_CONTEXT; 
+	 ctx->glClipPlanefIMG(ctx, plane, equation);
+}
+
+void glGetClipPlanefOES(GLenum pname, GLfloat* eqn)
+{
+	GET_CONTEXT; 
+	 ctx->glGetClipPlanefOES(ctx, pname, eqn);
+}
+
+void glClearDepthfOES(GLclampf depth)
+{
+	GET_CONTEXT; 
+	 ctx->glClearDepthfOES(ctx, depth);
+}
+
+void glTexGenfOES(GLenum coord, GLenum pname, GLfloat param)
+{
+	GET_CONTEXT; 
+	 ctx->glTexGenfOES(ctx, coord, pname, param);
+}
+
+void glTexGenfvOES(GLenum coord, GLenum pname, const GLfloat* params)
+{
+	GET_CONTEXT; 
+	 ctx->glTexGenfvOES(ctx, coord, pname, params);
+}
+
+void glTexGeniOES(GLenum coord, GLenum pname, GLint param)
+{
+	GET_CONTEXT; 
+	 ctx->glTexGeniOES(ctx, coord, pname, param);
+}
+
+void glTexGenivOES(GLenum coord, GLenum pname, const GLint* params)
+{
+	GET_CONTEXT; 
+	 ctx->glTexGenivOES(ctx, coord, pname, params);
+}
+
+void glTexGenxOES(GLenum coord, GLenum pname, GLfixed param)
+{
+	GET_CONTEXT; 
+	 ctx->glTexGenxOES(ctx, coord, pname, param);
+}
+
+void glTexGenxvOES(GLenum coord, GLenum pname, const GLfixed* params)
+{
+	GET_CONTEXT; 
+	 ctx->glTexGenxvOES(ctx, coord, pname, params);
+}
+
+void glGetTexGenfvOES(GLenum coord, GLenum pname, GLfloat* params)
+{
+	GET_CONTEXT; 
+	 ctx->glGetTexGenfvOES(ctx, coord, pname, params);
+}
+
+void glGetTexGenivOES(GLenum coord, GLenum pname, GLint* params)
+{
+	GET_CONTEXT; 
+	 ctx->glGetTexGenivOES(ctx, coord, pname, params);
+}
+
+void glGetTexGenxvOES(GLenum coord, GLenum pname, GLfixed* params)
+{
+	GET_CONTEXT; 
+	 ctx->glGetTexGenxvOES(ctx, coord, pname, params);
+}
+
+void glBindVertexArrayOES(GLuint array)
+{
+	GET_CONTEXT; 
+	 ctx->glBindVertexArrayOES(ctx, array);
+}
+
+void glDeleteVertexArraysOES(GLsizei n, const GLuint* arrays)
+{
+	GET_CONTEXT; 
+	 if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
+	 ctx->glDeleteVertexArraysOES(ctx, n, arrays);
+}
+
+void glGenVertexArraysOES(GLsizei n, GLuint* arrays)
+{
+	GET_CONTEXT; 
+	 if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
+	 ctx->glGenVertexArraysOES(ctx, n, arrays);
+}
+
+GLboolean glIsVertexArrayOES(GLuint array)
+{
+	GET_CONTEXT; 
+	 return ctx->glIsVertexArrayOES(ctx, array);
+}
+
+void glDiscardFramebufferEXT(GLenum target, GLsizei numAttachments, const GLenum* attachments)
+{
+	GET_CONTEXT; 
+	 ctx->glDiscardFramebufferEXT(ctx, target, numAttachments, attachments);
+}
+
+void glMultiDrawArraysEXT(GLenum mode, GLint* first, GLsizei* count, GLsizei primcount)
+{
+	GET_CONTEXT; 
+	 ctx->glMultiDrawArraysEXT(ctx, mode, first, count, primcount);
+}
+
+void glMultiDrawElementsEXT(GLenum mode, const GLsizei* count, GLenum type, const GLvoid** indices, GLsizei primcount)
+{
+	GET_CONTEXT; 
+	 ctx->glMultiDrawElementsEXT(ctx, mode, count, type, indices, primcount);
+}
+
+void glMultiDrawArraysSUN(GLenum mode, GLint* first, GLsizei* count, GLsizei primcount)
+{
+	GET_CONTEXT; 
+	 ctx->glMultiDrawArraysSUN(ctx, mode, first, count, primcount);
+}
+
+void glMultiDrawElementsSUN(GLenum mode, const GLsizei* count, GLenum type, const GLvoid** indices, GLsizei primcount)
+{
+	GET_CONTEXT; 
+	 ctx->glMultiDrawElementsSUN(ctx, mode, count, type, indices, primcount);
+}
+
+void glRenderbufferStorageMultisampleIMG(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
+{
+	GET_CONTEXT; 
+	 ctx->glRenderbufferStorageMultisampleIMG(ctx, target, samples, internalformat, width, height);
+}
+
+void glFramebufferTexture2DMultisampleIMG(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples)
+{
+	GET_CONTEXT; 
+	 ctx->glFramebufferTexture2DMultisampleIMG(ctx, target, attachment, textarget, texture, level, samples);
+}
+
+void glDeleteFencesNV(GLsizei n, const GLuint* fences)
+{
+	GET_CONTEXT; 
+	 if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
+	 ctx->glDeleteFencesNV(ctx, n, fences);
+}
+
+void glGenFencesNV(GLsizei n, GLuint* fences)
+{
+	GET_CONTEXT; 
+	 if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
+	 ctx->glGenFencesNV(ctx, n, fences);
+}
+
+GLboolean glIsFenceNV(GLuint fence)
+{
+	GET_CONTEXT; 
+	 return ctx->glIsFenceNV(ctx, fence);
+}
+
+GLboolean glTestFenceNV(GLuint fence)
+{
+	GET_CONTEXT; 
+	 return ctx->glTestFenceNV(ctx, fence);
+}
+
+void glGetFenceivNV(GLuint fence, GLenum pname, GLint* params)
+{
+	GET_CONTEXT; 
+	 ctx->glGetFenceivNV(ctx, fence, pname, params);
+}
+
+void glFinishFenceNV(GLuint fence)
+{
+	GET_CONTEXT; 
+	 ctx->glFinishFenceNV(ctx, fence);
+}
+
+void glSetFenceNV(GLuint fence, GLenum condition)
+{
+	GET_CONTEXT; 
+	 ctx->glSetFenceNV(ctx, fence, condition);
+}
+
+void glGetDriverControlsQCOM(GLint* num, GLsizei size, GLuint* driverControls)
+{
+	GET_CONTEXT; 
+	 ctx->glGetDriverControlsQCOM(ctx, num, size, driverControls);
+}
+
+void glGetDriverControlStringQCOM(GLuint driverControl, GLsizei bufSize, GLsizei* length, GLchar* driverControlString)
+{
+	GET_CONTEXT; 
+	 ctx->glGetDriverControlStringQCOM(ctx, driverControl, bufSize, length, driverControlString);
+}
+
+void glEnableDriverControlQCOM(GLuint driverControl)
+{
+	GET_CONTEXT; 
+	 ctx->glEnableDriverControlQCOM(ctx, driverControl);
+}
+
+void glDisableDriverControlQCOM(GLuint driverControl)
+{
+	GET_CONTEXT; 
+	 ctx->glDisableDriverControlQCOM(ctx, driverControl);
+}
+
+void glExtGetTexturesQCOM(GLuint* textures, GLint maxTextures, GLint* numTextures)
+{
+	GET_CONTEXT; 
+	 ctx->glExtGetTexturesQCOM(ctx, textures, maxTextures, numTextures);
+}
+
+void glExtGetBuffersQCOM(GLuint* buffers, GLint maxBuffers, GLint* numBuffers)
+{
+	GET_CONTEXT; 
+	 ctx->glExtGetBuffersQCOM(ctx, buffers, maxBuffers, numBuffers);
+}
+
+void glExtGetRenderbuffersQCOM(GLuint* renderbuffers, GLint maxRenderbuffers, GLint* numRenderbuffers)
+{
+	GET_CONTEXT; 
+	 ctx->glExtGetRenderbuffersQCOM(ctx, renderbuffers, maxRenderbuffers, numRenderbuffers);
+}
+
+void glExtGetFramebuffersQCOM(GLuint* framebuffers, GLint maxFramebuffers, GLint* numFramebuffers)
+{
+	GET_CONTEXT; 
+	 ctx->glExtGetFramebuffersQCOM(ctx, framebuffers, maxFramebuffers, numFramebuffers);
+}
+
+void glExtGetTexLevelParameterivQCOM(GLuint texture, GLenum face, GLint level, GLenum pname, GLint* params)
+{
+	GET_CONTEXT; 
+	 ctx->glExtGetTexLevelParameterivQCOM(ctx, texture, face, level, pname, params);
+}
+
+void glExtTexObjectStateOverrideiQCOM(GLenum target, GLenum pname, GLint param)
+{
+	GET_CONTEXT; 
+	 ctx->glExtTexObjectStateOverrideiQCOM(ctx, target, pname, param);
+}
+
+void glExtGetTexSubImageQCOM(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid* texels)
+{
+	GET_CONTEXT; 
+	 ctx->glExtGetTexSubImageQCOM(ctx, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, texels);
+}
+
+void glExtGetBufferPointervQCOM(GLenum target, GLvoid** params)
+{
+	GET_CONTEXT; 
+	 ctx->glExtGetBufferPointervQCOM(ctx, target, params);
+}
+
+void glExtGetShadersQCOM(GLuint* shaders, GLint maxShaders, GLint* numShaders)
+{
+	GET_CONTEXT; 
+	 ctx->glExtGetShadersQCOM(ctx, shaders, maxShaders, numShaders);
+}
+
+void glExtGetProgramsQCOM(GLuint* programs, GLint maxPrograms, GLint* numPrograms)
+{
+	GET_CONTEXT; 
+	 ctx->glExtGetProgramsQCOM(ctx, programs, maxPrograms, numPrograms);
+}
+
+GLboolean glExtIsProgramBinaryQCOM(GLuint program)
+{
+	GET_CONTEXT; 
+	 return ctx->glExtIsProgramBinaryQCOM(ctx, program);
+}
+
+void glExtGetProgramBinarySourceQCOM(GLuint program, GLenum shadertype, GLchar* source, GLint* length)
+{
+	GET_CONTEXT; 
+	 ctx->glExtGetProgramBinarySourceQCOM(ctx, program, shadertype, source, length);
+}
+
+void glStartTilingQCOM(GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask)
+{
+	GET_CONTEXT; 
+	 ctx->glStartTilingQCOM(ctx, x, y, width, height, preserveMask);
+}
+
+void glEndTilingQCOM(GLbitfield preserveMask)
+{
+	GET_CONTEXT; 
+	 ctx->glEndTilingQCOM(ctx, preserveMask);
+}
+
diff --git a/opengl/system/GLESv1_enc/gl_ftable.h b/opengl/system/GLESv1_enc/gl_ftable.h
new file mode 100644
index 0000000..7201e7f
--- /dev/null
+++ b/opengl/system/GLESv1_enc/gl_ftable.h
@@ -0,0 +1,288 @@
+// Generated Code - DO NOT EDIT !!
+// generated by 'emugen'
+#ifndef __gl_client_ftable_t_h
+#define __gl_client_ftable_t_h
+
+
+static struct _gl_funcs_by_name {
+	const char *name;
+	void *proc;
+} gl_funcs_by_name[] = {
+	{"glAlphaFunc", (void*)glAlphaFunc},
+	{"glClearColor", (void*)glClearColor},
+	{"glClearDepthf", (void*)glClearDepthf},
+	{"glClipPlanef", (void*)glClipPlanef},
+	{"glColor4f", (void*)glColor4f},
+	{"glDepthRangef", (void*)glDepthRangef},
+	{"glFogf", (void*)glFogf},
+	{"glFogfv", (void*)glFogfv},
+	{"glFrustumf", (void*)glFrustumf},
+	{"glGetClipPlanef", (void*)glGetClipPlanef},
+	{"glGetFloatv", (void*)glGetFloatv},
+	{"glGetLightfv", (void*)glGetLightfv},
+	{"glGetMaterialfv", (void*)glGetMaterialfv},
+	{"glGetTexEnvfv", (void*)glGetTexEnvfv},
+	{"glGetTexParameterfv", (void*)glGetTexParameterfv},
+	{"glLightModelf", (void*)glLightModelf},
+	{"glLightModelfv", (void*)glLightModelfv},
+	{"glLightf", (void*)glLightf},
+	{"glLightfv", (void*)glLightfv},
+	{"glLineWidth", (void*)glLineWidth},
+	{"glLoadMatrixf", (void*)glLoadMatrixf},
+	{"glMaterialf", (void*)glMaterialf},
+	{"glMaterialfv", (void*)glMaterialfv},
+	{"glMultMatrixf", (void*)glMultMatrixf},
+	{"glMultiTexCoord4f", (void*)glMultiTexCoord4f},
+	{"glNormal3f", (void*)glNormal3f},
+	{"glOrthof", (void*)glOrthof},
+	{"glPointParameterf", (void*)glPointParameterf},
+	{"glPointParameterfv", (void*)glPointParameterfv},
+	{"glPointSize", (void*)glPointSize},
+	{"glPolygonOffset", (void*)glPolygonOffset},
+	{"glRotatef", (void*)glRotatef},
+	{"glScalef", (void*)glScalef},
+	{"glTexEnvf", (void*)glTexEnvf},
+	{"glTexEnvfv", (void*)glTexEnvfv},
+	{"glTexParameterf", (void*)glTexParameterf},
+	{"glTexParameterfv", (void*)glTexParameterfv},
+	{"glTranslatef", (void*)glTranslatef},
+	{"glActiveTexture", (void*)glActiveTexture},
+	{"glAlphaFuncx", (void*)glAlphaFuncx},
+	{"glBindBuffer", (void*)glBindBuffer},
+	{"glBindTexture", (void*)glBindTexture},
+	{"glBlendFunc", (void*)glBlendFunc},
+	{"glBufferData", (void*)glBufferData},
+	{"glBufferSubData", (void*)glBufferSubData},
+	{"glClear", (void*)glClear},
+	{"glClearColorx", (void*)glClearColorx},
+	{"glClearDepthx", (void*)glClearDepthx},
+	{"glClearStencil", (void*)glClearStencil},
+	{"glClientActiveTexture", (void*)glClientActiveTexture},
+	{"glColor4ub", (void*)glColor4ub},
+	{"glColor4x", (void*)glColor4x},
+	{"glColorMask", (void*)glColorMask},
+	{"glColorPointer", (void*)glColorPointer},
+	{"glCompressedTexImage2D", (void*)glCompressedTexImage2D},
+	{"glCompressedTexSubImage2D", (void*)glCompressedTexSubImage2D},
+	{"glCopyTexImage2D", (void*)glCopyTexImage2D},
+	{"glCopyTexSubImage2D", (void*)glCopyTexSubImage2D},
+	{"glCullFace", (void*)glCullFace},
+	{"glDeleteBuffers", (void*)glDeleteBuffers},
+	{"glDeleteTextures", (void*)glDeleteTextures},
+	{"glDepthFunc", (void*)glDepthFunc},
+	{"glDepthMask", (void*)glDepthMask},
+	{"glDepthRangex", (void*)glDepthRangex},
+	{"glDisable", (void*)glDisable},
+	{"glDisableClientState", (void*)glDisableClientState},
+	{"glDrawArrays", (void*)glDrawArrays},
+	{"glDrawElements", (void*)glDrawElements},
+	{"glEnable", (void*)glEnable},
+	{"glEnableClientState", (void*)glEnableClientState},
+	{"glFinish", (void*)glFinish},
+	{"glFlush", (void*)glFlush},
+	{"glFogx", (void*)glFogx},
+	{"glFogxv", (void*)glFogxv},
+	{"glFrontFace", (void*)glFrontFace},
+	{"glFrustumx", (void*)glFrustumx},
+	{"glGetBooleanv", (void*)glGetBooleanv},
+	{"glGetBufferParameteriv", (void*)glGetBufferParameteriv},
+	{"glClipPlanex", (void*)glClipPlanex},
+	{"glGenBuffers", (void*)glGenBuffers},
+	{"glGenTextures", (void*)glGenTextures},
+	{"glGetError", (void*)glGetError},
+	{"glGetFixedv", (void*)glGetFixedv},
+	{"glGetIntegerv", (void*)glGetIntegerv},
+	{"glGetLightxv", (void*)glGetLightxv},
+	{"glGetMaterialxv", (void*)glGetMaterialxv},
+	{"glGetPointerv", (void*)glGetPointerv},
+	{"glGetString", (void*)glGetString},
+	{"glGetTexEnviv", (void*)glGetTexEnviv},
+	{"glGetTexEnvxv", (void*)glGetTexEnvxv},
+	{"glGetTexParameteriv", (void*)glGetTexParameteriv},
+	{"glGetTexParameterxv", (void*)glGetTexParameterxv},
+	{"glHint", (void*)glHint},
+	{"glIsBuffer", (void*)glIsBuffer},
+	{"glIsEnabled", (void*)glIsEnabled},
+	{"glIsTexture", (void*)glIsTexture},
+	{"glLightModelx", (void*)glLightModelx},
+	{"glLightModelxv", (void*)glLightModelxv},
+	{"glLightx", (void*)glLightx},
+	{"glLightxv", (void*)glLightxv},
+	{"glLineWidthx", (void*)glLineWidthx},
+	{"glLoadIdentity", (void*)glLoadIdentity},
+	{"glLoadMatrixx", (void*)glLoadMatrixx},
+	{"glLogicOp", (void*)glLogicOp},
+	{"glMaterialx", (void*)glMaterialx},
+	{"glMaterialxv", (void*)glMaterialxv},
+	{"glMatrixMode", (void*)glMatrixMode},
+	{"glMultMatrixx", (void*)glMultMatrixx},
+	{"glMultiTexCoord4x", (void*)glMultiTexCoord4x},
+	{"glNormal3x", (void*)glNormal3x},
+	{"glNormalPointer", (void*)glNormalPointer},
+	{"glOrthox", (void*)glOrthox},
+	{"glPixelStorei", (void*)glPixelStorei},
+	{"glPointParameterx", (void*)glPointParameterx},
+	{"glPointParameterxv", (void*)glPointParameterxv},
+	{"glPointSizex", (void*)glPointSizex},
+	{"glPolygonOffsetx", (void*)glPolygonOffsetx},
+	{"glPopMatrix", (void*)glPopMatrix},
+	{"glPushMatrix", (void*)glPushMatrix},
+	{"glReadPixels", (void*)glReadPixels},
+	{"glRotatex", (void*)glRotatex},
+	{"glSampleCoverage", (void*)glSampleCoverage},
+	{"glSampleCoveragex", (void*)glSampleCoveragex},
+	{"glScalex", (void*)glScalex},
+	{"glScissor", (void*)glScissor},
+	{"glShadeModel", (void*)glShadeModel},
+	{"glStencilFunc", (void*)glStencilFunc},
+	{"glStencilMask", (void*)glStencilMask},
+	{"glStencilOp", (void*)glStencilOp},
+	{"glTexCoordPointer", (void*)glTexCoordPointer},
+	{"glTexEnvi", (void*)glTexEnvi},
+	{"glTexEnvx", (void*)glTexEnvx},
+	{"glTexEnviv", (void*)glTexEnviv},
+	{"glTexEnvxv", (void*)glTexEnvxv},
+	{"glTexImage2D", (void*)glTexImage2D},
+	{"glTexParameteri", (void*)glTexParameteri},
+	{"glTexParameterx", (void*)glTexParameterx},
+	{"glTexParameteriv", (void*)glTexParameteriv},
+	{"glTexParameterxv", (void*)glTexParameterxv},
+	{"glTexSubImage2D", (void*)glTexSubImage2D},
+	{"glTranslatex", (void*)glTranslatex},
+	{"glVertexPointer", (void*)glVertexPointer},
+	{"glViewport", (void*)glViewport},
+	{"glPointSizePointerOES", (void*)glPointSizePointerOES},
+	{"glBlendEquationSeparateOES", (void*)glBlendEquationSeparateOES},
+	{"glBlendFuncSeparateOES", (void*)glBlendFuncSeparateOES},
+	{"glBlendEquationOES", (void*)glBlendEquationOES},
+	{"glDrawTexsOES", (void*)glDrawTexsOES},
+	{"glDrawTexiOES", (void*)glDrawTexiOES},
+	{"glDrawTexxOES", (void*)glDrawTexxOES},
+	{"glDrawTexsvOES", (void*)glDrawTexsvOES},
+	{"glDrawTexivOES", (void*)glDrawTexivOES},
+	{"glDrawTexxvOES", (void*)glDrawTexxvOES},
+	{"glDrawTexfOES", (void*)glDrawTexfOES},
+	{"glDrawTexfvOES", (void*)glDrawTexfvOES},
+	{"glEGLImageTargetTexture2DOES", (void*)glEGLImageTargetTexture2DOES},
+	{"glEGLImageTargetRenderbufferStorageOES", (void*)glEGLImageTargetRenderbufferStorageOES},
+	{"glAlphaFuncxOES", (void*)glAlphaFuncxOES},
+	{"glClearColorxOES", (void*)glClearColorxOES},
+	{"glClearDepthxOES", (void*)glClearDepthxOES},
+	{"glClipPlanexOES", (void*)glClipPlanexOES},
+	{"glClipPlanexIMG", (void*)glClipPlanexIMG},
+	{"glColor4xOES", (void*)glColor4xOES},
+	{"glDepthRangexOES", (void*)glDepthRangexOES},
+	{"glFogxOES", (void*)glFogxOES},
+	{"glFogxvOES", (void*)glFogxvOES},
+	{"glFrustumxOES", (void*)glFrustumxOES},
+	{"glGetClipPlanexOES", (void*)glGetClipPlanexOES},
+	{"glGetClipPlanex", (void*)glGetClipPlanex},
+	{"glGetFixedvOES", (void*)glGetFixedvOES},
+	{"glGetLightxvOES", (void*)glGetLightxvOES},
+	{"glGetMaterialxvOES", (void*)glGetMaterialxvOES},
+	{"glGetTexEnvxvOES", (void*)glGetTexEnvxvOES},
+	{"glGetTexParameterxvOES", (void*)glGetTexParameterxvOES},
+	{"glLightModelxOES", (void*)glLightModelxOES},
+	{"glLightModelxvOES", (void*)glLightModelxvOES},
+	{"glLightxOES", (void*)glLightxOES},
+	{"glLightxvOES", (void*)glLightxvOES},
+	{"glLineWidthxOES", (void*)glLineWidthxOES},
+	{"glLoadMatrixxOES", (void*)glLoadMatrixxOES},
+	{"glMaterialxOES", (void*)glMaterialxOES},
+	{"glMaterialxvOES", (void*)glMaterialxvOES},
+	{"glMultMatrixxOES", (void*)glMultMatrixxOES},
+	{"glMultiTexCoord4xOES", (void*)glMultiTexCoord4xOES},
+	{"glNormal3xOES", (void*)glNormal3xOES},
+	{"glOrthoxOES", (void*)glOrthoxOES},
+	{"glPointParameterxOES", (void*)glPointParameterxOES},
+	{"glPointParameterxvOES", (void*)glPointParameterxvOES},
+	{"glPointSizexOES", (void*)glPointSizexOES},
+	{"glPolygonOffsetxOES", (void*)glPolygonOffsetxOES},
+	{"glRotatexOES", (void*)glRotatexOES},
+	{"glSampleCoveragexOES", (void*)glSampleCoveragexOES},
+	{"glScalexOES", (void*)glScalexOES},
+	{"glTexEnvxOES", (void*)glTexEnvxOES},
+	{"glTexEnvxvOES", (void*)glTexEnvxvOES},
+	{"glTexParameterxOES", (void*)glTexParameterxOES},
+	{"glTexParameterxvOES", (void*)glTexParameterxvOES},
+	{"glTranslatexOES", (void*)glTranslatexOES},
+	{"glIsRenderbufferOES", (void*)glIsRenderbufferOES},
+	{"glBindRenderbufferOES", (void*)glBindRenderbufferOES},
+	{"glDeleteRenderbuffersOES", (void*)glDeleteRenderbuffersOES},
+	{"glGenRenderbuffersOES", (void*)glGenRenderbuffersOES},
+	{"glRenderbufferStorageOES", (void*)glRenderbufferStorageOES},
+	{"glGetRenderbufferParameterivOES", (void*)glGetRenderbufferParameterivOES},
+	{"glIsFramebufferOES", (void*)glIsFramebufferOES},
+	{"glBindFramebufferOES", (void*)glBindFramebufferOES},
+	{"glDeleteFramebuffersOES", (void*)glDeleteFramebuffersOES},
+	{"glGenFramebuffersOES", (void*)glGenFramebuffersOES},
+	{"glCheckFramebufferStatusOES", (void*)glCheckFramebufferStatusOES},
+	{"glFramebufferRenderbufferOES", (void*)glFramebufferRenderbufferOES},
+	{"glFramebufferTexture2DOES", (void*)glFramebufferTexture2DOES},
+	{"glGetFramebufferAttachmentParameterivOES", (void*)glGetFramebufferAttachmentParameterivOES},
+	{"glGenerateMipmapOES", (void*)glGenerateMipmapOES},
+	{"glMapBufferOES", (void*)glMapBufferOES},
+	{"glUnmapBufferOES", (void*)glUnmapBufferOES},
+	{"glGetBufferPointervOES", (void*)glGetBufferPointervOES},
+	{"glCurrentPaletteMatrixOES", (void*)glCurrentPaletteMatrixOES},
+	{"glLoadPaletteFromModelViewMatrixOES", (void*)glLoadPaletteFromModelViewMatrixOES},
+	{"glMatrixIndexPointerOES", (void*)glMatrixIndexPointerOES},
+	{"glWeightPointerOES", (void*)glWeightPointerOES},
+	{"glQueryMatrixxOES", (void*)glQueryMatrixxOES},
+	{"glDepthRangefOES", (void*)glDepthRangefOES},
+	{"glFrustumfOES", (void*)glFrustumfOES},
+	{"glOrthofOES", (void*)glOrthofOES},
+	{"glClipPlanefOES", (void*)glClipPlanefOES},
+	{"glClipPlanefIMG", (void*)glClipPlanefIMG},
+	{"glGetClipPlanefOES", (void*)glGetClipPlanefOES},
+	{"glClearDepthfOES", (void*)glClearDepthfOES},
+	{"glTexGenfOES", (void*)glTexGenfOES},
+	{"glTexGenfvOES", (void*)glTexGenfvOES},
+	{"glTexGeniOES", (void*)glTexGeniOES},
+	{"glTexGenivOES", (void*)glTexGenivOES},
+	{"glTexGenxOES", (void*)glTexGenxOES},
+	{"glTexGenxvOES", (void*)glTexGenxvOES},
+	{"glGetTexGenfvOES", (void*)glGetTexGenfvOES},
+	{"glGetTexGenivOES", (void*)glGetTexGenivOES},
+	{"glGetTexGenxvOES", (void*)glGetTexGenxvOES},
+	{"glBindVertexArrayOES", (void*)glBindVertexArrayOES},
+	{"glDeleteVertexArraysOES", (void*)glDeleteVertexArraysOES},
+	{"glGenVertexArraysOES", (void*)glGenVertexArraysOES},
+	{"glIsVertexArrayOES", (void*)glIsVertexArrayOES},
+	{"glDiscardFramebufferEXT", (void*)glDiscardFramebufferEXT},
+	{"glMultiDrawArraysEXT", (void*)glMultiDrawArraysEXT},
+	{"glMultiDrawElementsEXT", (void*)glMultiDrawElementsEXT},
+	{"glMultiDrawArraysSUN", (void*)glMultiDrawArraysSUN},
+	{"glMultiDrawElementsSUN", (void*)glMultiDrawElementsSUN},
+	{"glRenderbufferStorageMultisampleIMG", (void*)glRenderbufferStorageMultisampleIMG},
+	{"glFramebufferTexture2DMultisampleIMG", (void*)glFramebufferTexture2DMultisampleIMG},
+	{"glDeleteFencesNV", (void*)glDeleteFencesNV},
+	{"glGenFencesNV", (void*)glGenFencesNV},
+	{"glIsFenceNV", (void*)glIsFenceNV},
+	{"glTestFenceNV", (void*)glTestFenceNV},
+	{"glGetFenceivNV", (void*)glGetFenceivNV},
+	{"glFinishFenceNV", (void*)glFinishFenceNV},
+	{"glSetFenceNV", (void*)glSetFenceNV},
+	{"glGetDriverControlsQCOM", (void*)glGetDriverControlsQCOM},
+	{"glGetDriverControlStringQCOM", (void*)glGetDriverControlStringQCOM},
+	{"glEnableDriverControlQCOM", (void*)glEnableDriverControlQCOM},
+	{"glDisableDriverControlQCOM", (void*)glDisableDriverControlQCOM},
+	{"glExtGetTexturesQCOM", (void*)glExtGetTexturesQCOM},
+	{"glExtGetBuffersQCOM", (void*)glExtGetBuffersQCOM},
+	{"glExtGetRenderbuffersQCOM", (void*)glExtGetRenderbuffersQCOM},
+	{"glExtGetFramebuffersQCOM", (void*)glExtGetFramebuffersQCOM},
+	{"glExtGetTexLevelParameterivQCOM", (void*)glExtGetTexLevelParameterivQCOM},
+	{"glExtTexObjectStateOverrideiQCOM", (void*)glExtTexObjectStateOverrideiQCOM},
+	{"glExtGetTexSubImageQCOM", (void*)glExtGetTexSubImageQCOM},
+	{"glExtGetBufferPointervQCOM", (void*)glExtGetBufferPointervQCOM},
+	{"glExtGetShadersQCOM", (void*)glExtGetShadersQCOM},
+	{"glExtGetProgramsQCOM", (void*)glExtGetProgramsQCOM},
+	{"glExtIsProgramBinaryQCOM", (void*)glExtIsProgramBinaryQCOM},
+	{"glExtGetProgramBinarySourceQCOM", (void*)glExtGetProgramBinarySourceQCOM},
+	{"glStartTilingQCOM", (void*)glStartTilingQCOM},
+	{"glEndTilingQCOM", (void*)glEndTilingQCOM},
+};
+static int gl_num_funcs = sizeof(gl_funcs_by_name) / sizeof(struct _gl_funcs_by_name);
+
+
+#endif
diff --git a/opengl/system/GLESv1_enc/gl_opcodes.h b/opengl/system/GLESv1_enc/gl_opcodes.h
new file mode 100644
index 0000000..319d0a1
--- /dev/null
+++ b/opengl/system/GLESv1_enc/gl_opcodes.h
@@ -0,0 +1,300 @@
+// Generated Code - DO NOT EDIT !!
+// generated by 'emugen'
+#ifndef __GUARD_gl_opcodes_h_
+#define __GUARD_gl_opcodes_h_
+
+#define OP_glAlphaFunc 					1024
+#define OP_glClearColor 					1025
+#define OP_glClearDepthf 					1026
+#define OP_glClipPlanef 					1027
+#define OP_glColor4f 					1028
+#define OP_glDepthRangef 					1029
+#define OP_glFogf 					1030
+#define OP_glFogfv 					1031
+#define OP_glFrustumf 					1032
+#define OP_glGetClipPlanef 					1033
+#define OP_glGetFloatv 					1034
+#define OP_glGetLightfv 					1035
+#define OP_glGetMaterialfv 					1036
+#define OP_glGetTexEnvfv 					1037
+#define OP_glGetTexParameterfv 					1038
+#define OP_glLightModelf 					1039
+#define OP_glLightModelfv 					1040
+#define OP_glLightf 					1041
+#define OP_glLightfv 					1042
+#define OP_glLineWidth 					1043
+#define OP_glLoadMatrixf 					1044
+#define OP_glMaterialf 					1045
+#define OP_glMaterialfv 					1046
+#define OP_glMultMatrixf 					1047
+#define OP_glMultiTexCoord4f 					1048
+#define OP_glNormal3f 					1049
+#define OP_glOrthof 					1050
+#define OP_glPointParameterf 					1051
+#define OP_glPointParameterfv 					1052
+#define OP_glPointSize 					1053
+#define OP_glPolygonOffset 					1054
+#define OP_glRotatef 					1055
+#define OP_glScalef 					1056
+#define OP_glTexEnvf 					1057
+#define OP_glTexEnvfv 					1058
+#define OP_glTexParameterf 					1059
+#define OP_glTexParameterfv 					1060
+#define OP_glTranslatef 					1061
+#define OP_glActiveTexture 					1062
+#define OP_glAlphaFuncx 					1063
+#define OP_glBindBuffer 					1064
+#define OP_glBindTexture 					1065
+#define OP_glBlendFunc 					1066
+#define OP_glBufferData 					1067
+#define OP_glBufferSubData 					1068
+#define OP_glClear 					1069
+#define OP_glClearColorx 					1070
+#define OP_glClearDepthx 					1071
+#define OP_glClearStencil 					1072
+#define OP_glClientActiveTexture 					1073
+#define OP_glColor4ub 					1074
+#define OP_glColor4x 					1075
+#define OP_glColorMask 					1076
+#define OP_glColorPointer 					1077
+#define OP_glCompressedTexImage2D 					1078
+#define OP_glCompressedTexSubImage2D 					1079
+#define OP_glCopyTexImage2D 					1080
+#define OP_glCopyTexSubImage2D 					1081
+#define OP_glCullFace 					1082
+#define OP_glDeleteBuffers 					1083
+#define OP_glDeleteTextures 					1084
+#define OP_glDepthFunc 					1085
+#define OP_glDepthMask 					1086
+#define OP_glDepthRangex 					1087
+#define OP_glDisable 					1088
+#define OP_glDisableClientState 					1089
+#define OP_glDrawArrays 					1090
+#define OP_glDrawElements 					1091
+#define OP_glEnable 					1092
+#define OP_glEnableClientState 					1093
+#define OP_glFinish 					1094
+#define OP_glFlush 					1095
+#define OP_glFogx 					1096
+#define OP_glFogxv 					1097
+#define OP_glFrontFace 					1098
+#define OP_glFrustumx 					1099
+#define OP_glGetBooleanv 					1100
+#define OP_glGetBufferParameteriv 					1101
+#define OP_glClipPlanex 					1102
+#define OP_glGenBuffers 					1103
+#define OP_glGenTextures 					1104
+#define OP_glGetError 					1105
+#define OP_glGetFixedv 					1106
+#define OP_glGetIntegerv 					1107
+#define OP_glGetLightxv 					1108
+#define OP_glGetMaterialxv 					1109
+#define OP_glGetPointerv 					1110
+#define OP_glGetString 					1111
+#define OP_glGetTexEnviv 					1112
+#define OP_glGetTexEnvxv 					1113
+#define OP_glGetTexParameteriv 					1114
+#define OP_glGetTexParameterxv 					1115
+#define OP_glHint 					1116
+#define OP_glIsBuffer 					1117
+#define OP_glIsEnabled 					1118
+#define OP_glIsTexture 					1119
+#define OP_glLightModelx 					1120
+#define OP_glLightModelxv 					1121
+#define OP_glLightx 					1122
+#define OP_glLightxv 					1123
+#define OP_glLineWidthx 					1124
+#define OP_glLoadIdentity 					1125
+#define OP_glLoadMatrixx 					1126
+#define OP_glLogicOp 					1127
+#define OP_glMaterialx 					1128
+#define OP_glMaterialxv 					1129
+#define OP_glMatrixMode 					1130
+#define OP_glMultMatrixx 					1131
+#define OP_glMultiTexCoord4x 					1132
+#define OP_glNormal3x 					1133
+#define OP_glNormalPointer 					1134
+#define OP_glOrthox 					1135
+#define OP_glPixelStorei 					1136
+#define OP_glPointParameterx 					1137
+#define OP_glPointParameterxv 					1138
+#define OP_glPointSizex 					1139
+#define OP_glPolygonOffsetx 					1140
+#define OP_glPopMatrix 					1141
+#define OP_glPushMatrix 					1142
+#define OP_glReadPixels 					1143
+#define OP_glRotatex 					1144
+#define OP_glSampleCoverage 					1145
+#define OP_glSampleCoveragex 					1146
+#define OP_glScalex 					1147
+#define OP_glScissor 					1148
+#define OP_glShadeModel 					1149
+#define OP_glStencilFunc 					1150
+#define OP_glStencilMask 					1151
+#define OP_glStencilOp 					1152
+#define OP_glTexCoordPointer 					1153
+#define OP_glTexEnvi 					1154
+#define OP_glTexEnvx 					1155
+#define OP_glTexEnviv 					1156
+#define OP_glTexEnvxv 					1157
+#define OP_glTexImage2D 					1158
+#define OP_glTexParameteri 					1159
+#define OP_glTexParameterx 					1160
+#define OP_glTexParameteriv 					1161
+#define OP_glTexParameterxv 					1162
+#define OP_glTexSubImage2D 					1163
+#define OP_glTranslatex 					1164
+#define OP_glVertexPointer 					1165
+#define OP_glViewport 					1166
+#define OP_glPointSizePointerOES 					1167
+#define OP_glVertexPointerOffset 					1168
+#define OP_glColorPointerOffset 					1169
+#define OP_glNormalPointerOffset 					1170
+#define OP_glPointSizePointerOffset 					1171
+#define OP_glTexCoordPointerOffset 					1172
+#define OP_glWeightPointerOffset 					1173
+#define OP_glMatrixIndexPointerOffset 					1174
+#define OP_glVertexPointerData 					1175
+#define OP_glColorPointerData 					1176
+#define OP_glNormalPointerData 					1177
+#define OP_glTexCoordPointerData 					1178
+#define OP_glPointSizePointerData 					1179
+#define OP_glWeightPointerData 					1180
+#define OP_glMatrixIndexPointerData 					1181
+#define OP_glDrawElementsOffset 					1182
+#define OP_glDrawElementsData 					1183
+#define OP_glGetCompressedTextureFormats 					1184
+#define OP_glFinishRoundTrip 					1185
+#define OP_glBlendEquationSeparateOES 					1186
+#define OP_glBlendFuncSeparateOES 					1187
+#define OP_glBlendEquationOES 					1188
+#define OP_glDrawTexsOES 					1189
+#define OP_glDrawTexiOES 					1190
+#define OP_glDrawTexxOES 					1191
+#define OP_glDrawTexsvOES 					1192
+#define OP_glDrawTexivOES 					1193
+#define OP_glDrawTexxvOES 					1194
+#define OP_glDrawTexfOES 					1195
+#define OP_glDrawTexfvOES 					1196
+#define OP_glEGLImageTargetTexture2DOES 					1197
+#define OP_glEGLImageTargetRenderbufferStorageOES 					1198
+#define OP_glAlphaFuncxOES 					1199
+#define OP_glClearColorxOES 					1200
+#define OP_glClearDepthxOES 					1201
+#define OP_glClipPlanexOES 					1202
+#define OP_glClipPlanexIMG 					1203
+#define OP_glColor4xOES 					1204
+#define OP_glDepthRangexOES 					1205
+#define OP_glFogxOES 					1206
+#define OP_glFogxvOES 					1207
+#define OP_glFrustumxOES 					1208
+#define OP_glGetClipPlanexOES 					1209
+#define OP_glGetClipPlanex 					1210
+#define OP_glGetFixedvOES 					1211
+#define OP_glGetLightxvOES 					1212
+#define OP_glGetMaterialxvOES 					1213
+#define OP_glGetTexEnvxvOES 					1214
+#define OP_glGetTexParameterxvOES 					1215
+#define OP_glLightModelxOES 					1216
+#define OP_glLightModelxvOES 					1217
+#define OP_glLightxOES 					1218
+#define OP_glLightxvOES 					1219
+#define OP_glLineWidthxOES 					1220
+#define OP_glLoadMatrixxOES 					1221
+#define OP_glMaterialxOES 					1222
+#define OP_glMaterialxvOES 					1223
+#define OP_glMultMatrixxOES 					1224
+#define OP_glMultiTexCoord4xOES 					1225
+#define OP_glNormal3xOES 					1226
+#define OP_glOrthoxOES 					1227
+#define OP_glPointParameterxOES 					1228
+#define OP_glPointParameterxvOES 					1229
+#define OP_glPointSizexOES 					1230
+#define OP_glPolygonOffsetxOES 					1231
+#define OP_glRotatexOES 					1232
+#define OP_glSampleCoveragexOES 					1233
+#define OP_glScalexOES 					1234
+#define OP_glTexEnvxOES 					1235
+#define OP_glTexEnvxvOES 					1236
+#define OP_glTexParameterxOES 					1237
+#define OP_glTexParameterxvOES 					1238
+#define OP_glTranslatexOES 					1239
+#define OP_glIsRenderbufferOES 					1240
+#define OP_glBindRenderbufferOES 					1241
+#define OP_glDeleteRenderbuffersOES 					1242
+#define OP_glGenRenderbuffersOES 					1243
+#define OP_glRenderbufferStorageOES 					1244
+#define OP_glGetRenderbufferParameterivOES 					1245
+#define OP_glIsFramebufferOES 					1246
+#define OP_glBindFramebufferOES 					1247
+#define OP_glDeleteFramebuffersOES 					1248
+#define OP_glGenFramebuffersOES 					1249
+#define OP_glCheckFramebufferStatusOES 					1250
+#define OP_glFramebufferRenderbufferOES 					1251
+#define OP_glFramebufferTexture2DOES 					1252
+#define OP_glGetFramebufferAttachmentParameterivOES 					1253
+#define OP_glGenerateMipmapOES 					1254
+#define OP_glMapBufferOES 					1255
+#define OP_glUnmapBufferOES 					1256
+#define OP_glGetBufferPointervOES 					1257
+#define OP_glCurrentPaletteMatrixOES 					1258
+#define OP_glLoadPaletteFromModelViewMatrixOES 					1259
+#define OP_glMatrixIndexPointerOES 					1260
+#define OP_glWeightPointerOES 					1261
+#define OP_glQueryMatrixxOES 					1262
+#define OP_glDepthRangefOES 					1263
+#define OP_glFrustumfOES 					1264
+#define OP_glOrthofOES 					1265
+#define OP_glClipPlanefOES 					1266
+#define OP_glClipPlanefIMG 					1267
+#define OP_glGetClipPlanefOES 					1268
+#define OP_glClearDepthfOES 					1269
+#define OP_glTexGenfOES 					1270
+#define OP_glTexGenfvOES 					1271
+#define OP_glTexGeniOES 					1272
+#define OP_glTexGenivOES 					1273
+#define OP_glTexGenxOES 					1274
+#define OP_glTexGenxvOES 					1275
+#define OP_glGetTexGenfvOES 					1276
+#define OP_glGetTexGenivOES 					1277
+#define OP_glGetTexGenxvOES 					1278
+#define OP_glBindVertexArrayOES 					1279
+#define OP_glDeleteVertexArraysOES 					1280
+#define OP_glGenVertexArraysOES 					1281
+#define OP_glIsVertexArrayOES 					1282
+#define OP_glDiscardFramebufferEXT 					1283
+#define OP_glMultiDrawArraysEXT 					1284
+#define OP_glMultiDrawElementsEXT 					1285
+#define OP_glMultiDrawArraysSUN 					1286
+#define OP_glMultiDrawElementsSUN 					1287
+#define OP_glRenderbufferStorageMultisampleIMG 					1288
+#define OP_glFramebufferTexture2DMultisampleIMG 					1289
+#define OP_glDeleteFencesNV 					1290
+#define OP_glGenFencesNV 					1291
+#define OP_glIsFenceNV 					1292
+#define OP_glTestFenceNV 					1293
+#define OP_glGetFenceivNV 					1294
+#define OP_glFinishFenceNV 					1295
+#define OP_glSetFenceNV 					1296
+#define OP_glGetDriverControlsQCOM 					1297
+#define OP_glGetDriverControlStringQCOM 					1298
+#define OP_glEnableDriverControlQCOM 					1299
+#define OP_glDisableDriverControlQCOM 					1300
+#define OP_glExtGetTexturesQCOM 					1301
+#define OP_glExtGetBuffersQCOM 					1302
+#define OP_glExtGetRenderbuffersQCOM 					1303
+#define OP_glExtGetFramebuffersQCOM 					1304
+#define OP_glExtGetTexLevelParameterivQCOM 					1305
+#define OP_glExtTexObjectStateOverrideiQCOM 					1306
+#define OP_glExtGetTexSubImageQCOM 					1307
+#define OP_glExtGetBufferPointervQCOM 					1308
+#define OP_glExtGetShadersQCOM 					1309
+#define OP_glExtGetProgramsQCOM 					1310
+#define OP_glExtIsProgramBinaryQCOM 					1311
+#define OP_glExtGetProgramBinarySourceQCOM 					1312
+#define OP_glStartTilingQCOM 					1313
+#define OP_glEndTilingQCOM 					1314
+#define OP_last 					1315
+
+
+#endif
diff --git a/opengl/system/GLESv1_enc/gl_types.h b/opengl/system/GLESv1_enc/gl_types.h
new file mode 100644
index 0000000..36fabfb
--- /dev/null
+++ b/opengl/system/GLESv1_enc/gl_types.h
@@ -0,0 +1,20 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#ifndef __GL_TYPES__H
+#define __GL_TYPES__H
+
+#include "gl_base_types.h"
+#endif
diff --git a/opengl/system/GLESv2/Android.mk b/opengl/system/GLESv2/Android.mk
new file mode 100644
index 0000000..c299522
--- /dev/null
+++ b/opengl/system/GLESv2/Android.mk
@@ -0,0 +1,12 @@
+LOCAL_PATH := $(call my-dir)
+
+### GLESv2 implementation ###########################################
+$(call emugl-begin-shared-library,libGLESv2_emulation)
+$(call emugl-import,libOpenglSystemCommon libGLESv2_enc lib_renderControl_enc)
+
+LOCAL_CFLAGS += -DLOG_TAG=\"GLESv2_emulation\" -DGL_GLEXT_PROTOTYPES
+
+LOCAL_SRC_FILES := gl2.cpp
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/egl
+
+$(call emugl-end-module)
diff --git a/opengl/system/GLESv2/gl2.cpp b/opengl/system/GLESv2/gl2.cpp
new file mode 100644
index 0000000..b32dd74
--- /dev/null
+++ b/opengl/system/GLESv2/gl2.cpp
@@ -0,0 +1,143 @@
+/*
+* Copyright 2011 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.
+*/
+
+#include "EGLClientIface.h"
+#include "HostConnection.h"
+#include "GL2Encoder.h"
+#include "GLES/gl.h"
+#include "GLES/glext.h"
+#include "ErrorLog.h"
+#include "gralloc_cb.h"
+#include "ThreadInfo.h"
+
+//XXX: fix this macro to get the context from fast tls path
+#define GET_CONTEXT GL2Encoder * ctx = getEGLThreadInfo()->hostConn->gl2Encoder();
+
+#include "gl2_entry.cpp"
+
+//The functions table
+#include "gl2_ftable.h"
+
+
+static EGLClient_eglInterface * s_egl = NULL;
+static EGLClient_glesInterface * s_gl = NULL;
+
+#define DEFINE_AND_VALIDATE_HOST_CONNECTION(ret) \
+    HostConnection *hostCon = HostConnection::get(); \
+    if (!hostCon) { \
+        ALOGE("egl: Failed to get host connection\n"); \
+        return ret; \
+    } \
+    renderControl_encoder_context_t *rcEnc = hostCon->rcEncoder(); \
+    if (!rcEnc) { \
+        ALOGE("egl: Failed to get renderControl encoder context\n"); \
+        return ret; \
+    }
+
+//GL extensions
+void glEGLImageTargetTexture2DOES(void * self, GLenum target, GLeglImageOES image)
+{
+    DBG("glEGLImageTargetTexture2DOES v2 target=%#x img=%p\n", target, image);
+    //TODO: check error - we don't have a way to set gl error
+    android_native_buffer_t* native_buffer = (android_native_buffer_t*)image;
+
+    if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) {
+        return;
+    }
+
+    if (native_buffer->common.version != sizeof(android_native_buffer_t)) {
+        return;
+    }
+
+    GET_CONTEXT;
+    DEFINE_AND_VALIDATE_HOST_CONNECTION();
+
+    ctx->override2DTextureTarget(target);
+    rcEnc->rcBindTexture(rcEnc, ((cb_handle_t *)(native_buffer->handle))->hostHandle);
+    ctx->restore2DTextureTarget();
+
+    return;
+}
+
+void glEGLImageTargetRenderbufferStorageOES(void *self, GLenum target, GLeglImageOES image)
+{
+    DBG("glEGLImageTargetRenderbufferStorageOES v2 image=%p\n", image);
+    //TODO: check error - we don't have a way to set gl error
+    android_native_buffer_t* native_buffer = (android_native_buffer_t*)image;
+
+    if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) {
+        return;
+    }
+
+    if (native_buffer->common.version != sizeof(android_native_buffer_t)) {
+        return;
+    }
+
+    DEFINE_AND_VALIDATE_HOST_CONNECTION();
+    rcEnc->rcBindRenderbuffer(rcEnc, ((cb_handle_t *)(native_buffer->handle))->hostHandle);
+
+    return;
+}
+
+void * getProcAddress(const char * procname)
+{
+    // search in GL function table
+    for (int i=0; i<gl2_num_funcs; i++) {
+        if (!strcmp(gl2_funcs_by_name[i].name, procname)) {
+            return gl2_funcs_by_name[i].proc;
+        }
+    }
+    return NULL;
+}
+
+void finish()
+{
+    glFinish();
+}
+
+const GLubyte *my_glGetString (void *self, GLenum name)
+{
+    if (s_egl) {
+        return (const GLubyte*)s_egl->getGLString(name);
+    }
+    return NULL;
+}
+
+void init()
+{
+    GET_CONTEXT;
+    ctx->set_glEGLImageTargetTexture2DOES(glEGLImageTargetTexture2DOES);
+    ctx->set_glEGLImageTargetRenderbufferStorageOES(glEGLImageTargetRenderbufferStorageOES);
+    ctx->set_glGetString(my_glGetString);
+}
+
+extern "C" {
+EGLClient_glesInterface * init_emul_gles(EGLClient_eglInterface *eglIface)
+{
+    s_egl = eglIface;
+
+    if (!s_gl) {
+        s_gl = new EGLClient_glesInterface();
+        s_gl->getProcAddress = getProcAddress;
+        s_gl->finish = finish;
+        s_gl->init = init;
+    }
+
+    return s_gl;
+}
+} //extern
+
+
diff --git a/opengl/system/GLESv2_enc/Android.mk b/opengl/system/GLESv2_enc/Android.mk
new file mode 100644
index 0000000..e76a175
--- /dev/null
+++ b/opengl/system/GLESv2_enc/Android.mk
@@ -0,0 +1,20 @@
+LOCAL_PATH := $(call my-dir)
+
+### GLESv2_enc Encoder ###########################################
+$(call emugl-begin-shared-library,libGLESv2_enc)
+
+LOCAL_SRC_FILES := \
+    GL2EncoderUtils.cpp \
+    GL2Encoder.cpp \
+    gl2_client_context.cpp \
+    gl2_enc.cpp \
+    gl2_entry.cpp
+
+LOCAL_CFLAGS += -DLOG_TAG=\"emuglGLESv2_enc\"
+
+$(call emugl-export,C_INCLUDES,$(LOCAL_PATH))
+$(call emugl-import,libOpenglCodecCommon)
+
+$(call emugl-end-module)
+
+
diff --git a/opengl/system/GLESv2_enc/GL2Encoder.cpp b/opengl/system/GLESv2_enc/GL2Encoder.cpp
new file mode 100644
index 0000000..7fc32b5
--- /dev/null
+++ b/opengl/system/GLESv2_enc/GL2Encoder.cpp
@@ -0,0 +1,1197 @@
+/*
+* Copyright (C) 2011 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.
+*/
+
+#include "GL2Encoder.h"
+#include <assert.h>
+#include <ctype.h>
+
+#ifndef MIN
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#endif
+
+static GLubyte *gVendorString= (GLubyte *) "Android";
+static GLubyte *gRendererString= (GLubyte *) "Android HW-GLES 2.0";
+static GLubyte *gVersionString= (GLubyte *) "OpenGL ES 2.0";
+static GLubyte *gExtensionsString= (GLubyte *) ""; // no extensions at this point;
+
+#define SET_ERROR_IF(condition,err) if((condition)) {                            \
+        ALOGE("%s:%s:%d GL error 0x%x\n", __FILE__, __FUNCTION__, __LINE__, err); \
+        ctx->setError(err);                                    \
+        return;                                                  \
+    }
+
+
+#define RET_AND_SET_ERROR_IF(condition,err,ret) if((condition)) {                \
+        ALOGE("%s:%s:%d GL error 0x%x\n", __FILE__, __FUNCTION__, __LINE__, err); \
+        ctx->setError(err);                                    \
+        return ret;                                              \
+    }
+
+
+GL2Encoder::GL2Encoder(IOStream *stream) : gl2_encoder_context_t(stream)
+{
+    m_initialized = false;
+    m_state = NULL;
+    m_error = GL_NO_ERROR;
+    m_num_compressedTextureFormats = 0;
+    m_compressedTextureFormats = NULL;
+    //overrides
+    m_glFlush_enc = set_glFlush(s_glFlush);
+    m_glPixelStorei_enc = set_glPixelStorei(s_glPixelStorei);
+    m_glGetString_enc = set_glGetString(s_glGetString);
+    m_glBindBuffer_enc = set_glBindBuffer(s_glBindBuffer);
+    m_glBufferData_enc = set_glBufferData(s_glBufferData);
+    m_glBufferSubData_enc = set_glBufferSubData(s_glBufferSubData);
+    m_glDeleteBuffers_enc = set_glDeleteBuffers(s_glDeleteBuffers);
+    m_glDrawArrays_enc = set_glDrawArrays(s_glDrawArrays);
+    m_glDrawElements_enc = set_glDrawElements(s_glDrawElements);
+    m_glGetIntegerv_enc = set_glGetIntegerv(s_glGetIntegerv);
+    m_glGetFloatv_enc = set_glGetFloatv(s_glGetFloatv);
+    m_glGetBooleanv_enc = set_glGetBooleanv(s_glGetBooleanv);
+    m_glVertexAttribPointer_enc = set_glVertexAttribPointer(s_glVertexAtrribPointer);
+    m_glEnableVertexAttribArray_enc = set_glEnableVertexAttribArray(s_glEnableVertexAttribArray);
+    m_glDisableVertexAttribArray_enc = set_glDisableVertexAttribArray(s_glDisableVertexAttribArray);
+    m_glGetVertexAttribiv_enc = set_glGetVertexAttribiv(s_glGetVertexAttribiv);
+    m_glGetVertexAttribfv_enc = set_glGetVertexAttribfv(s_glGetVertexAttribfv);
+    m_glGetVertexAttribPointerv = set_glGetVertexAttribPointerv(s_glGetVertexAttribPointerv);
+    set_glShaderSource(s_glShaderSource);
+    set_glFinish(s_glFinish);
+    m_glGetError_enc = set_glGetError(s_glGetError);
+    m_glLinkProgram_enc = set_glLinkProgram(s_glLinkProgram);
+    m_glDeleteProgram_enc = set_glDeleteProgram(s_glDeleteProgram);
+    m_glGetUniformiv_enc = set_glGetUniformiv(s_glGetUniformiv);
+    m_glGetUniformfv_enc = set_glGetUniformfv(s_glGetUniformfv);
+    m_glCreateProgram_enc = set_glCreateProgram(s_glCreateProgram);
+    m_glCreateShader_enc = set_glCreateShader(s_glCreateShader);
+    m_glDeleteShader_enc = set_glDeleteShader(s_glDeleteShader);
+    m_glAttachShader_enc = set_glAttachShader(s_glAttachShader);
+    m_glDetachShader_enc = set_glDetachShader(s_glDetachShader);
+    m_glGetUniformLocation_enc = set_glGetUniformLocation(s_glGetUniformLocation);
+    m_glUseProgram_enc = set_glUseProgram(s_glUseProgram);
+
+    m_glUniform1f_enc = set_glUniform1f(s_glUniform1f);
+    m_glUniform1fv_enc = set_glUniform1fv(s_glUniform1fv);
+    m_glUniform1i_enc = set_glUniform1i(s_glUniform1i);
+    m_glUniform1iv_enc = set_glUniform1iv(s_glUniform1iv);
+    m_glUniform2f_enc = set_glUniform2f(s_glUniform2f);
+    m_glUniform2fv_enc = set_glUniform2fv(s_glUniform2fv);
+    m_glUniform2i_enc = set_glUniform2i(s_glUniform2i);
+    m_glUniform2iv_enc = set_glUniform2iv(s_glUniform2iv);
+    m_glUniform3f_enc = set_glUniform3f(s_glUniform3f);
+    m_glUniform3fv_enc = set_glUniform3fv(s_glUniform3fv);
+    m_glUniform3i_enc = set_glUniform3i(s_glUniform3i);
+    m_glUniform3iv_enc = set_glUniform3iv(s_glUniform3iv);
+    m_glUniform4f_enc = set_glUniform4f(s_glUniform4f);
+    m_glUniform4fv_enc = set_glUniform4fv(s_glUniform4fv);
+    m_glUniform4i_enc = set_glUniform4i(s_glUniform4i);
+    m_glUniform4iv_enc = set_glUniform4iv(s_glUniform4iv);
+    m_glUniformMatrix2fv_enc = set_glUniformMatrix2fv(s_glUniformMatrix2fv);
+    m_glUniformMatrix3fv_enc = set_glUniformMatrix3fv(s_glUniformMatrix3fv);
+    m_glUniformMatrix4fv_enc = set_glUniformMatrix4fv(s_glUniformMatrix4fv);
+
+    m_glActiveTexture_enc = set_glActiveTexture(s_glActiveTexture);
+    m_glBindTexture_enc = set_glBindTexture(s_glBindTexture);
+    m_glDeleteTextures_enc = set_glDeleteTextures(s_glDeleteTextures);
+    m_glGetTexParameterfv_enc = set_glGetTexParameterfv(s_glGetTexParameterfv);
+    m_glGetTexParameteriv_enc = set_glGetTexParameteriv(s_glGetTexParameteriv);
+    m_glTexParameterf_enc = set_glTexParameterf(s_glTexParameterf);
+    m_glTexParameterfv_enc = set_glTexParameterfv(s_glTexParameterfv);
+    m_glTexParameteri_enc = set_glTexParameteri(s_glTexParameteri);
+    m_glTexParameteriv_enc = set_glTexParameteriv(s_glTexParameteriv);
+}
+
+GL2Encoder::~GL2Encoder()
+{
+    delete m_compressedTextureFormats;
+}
+
+GLenum GL2Encoder::s_glGetError(void * self)
+{
+    GL2Encoder *ctx = (GL2Encoder *)self;
+    GLenum err = ctx->getError();
+    if(err != GL_NO_ERROR) {
+        ctx->setError(GL_NO_ERROR);
+        return err;
+    }
+
+    return ctx->m_glGetError_enc(self);
+
+}
+
+void GL2Encoder::s_glFlush(void *self)
+{
+    GL2Encoder *ctx = (GL2Encoder *) self;
+    ctx->m_glFlush_enc(self);
+    ctx->m_stream->flush();
+}
+
+const GLubyte *GL2Encoder::s_glGetString(void *self, GLenum name)
+{
+    GLubyte *retval =  (GLubyte *) "";
+    switch(name) {
+    case GL_VENDOR:
+        retval = gVendorString;
+        break;
+    case GL_RENDERER:
+        retval = gRendererString;
+        break;
+    case GL_VERSION:
+        retval = gVersionString;
+        break;
+    case GL_EXTENSIONS:
+        retval = gExtensionsString;
+        break;
+    }
+    return retval;
+}
+
+void GL2Encoder::s_glPixelStorei(void *self, GLenum param, GLint value)
+{
+    GL2Encoder *ctx = (GL2Encoder *)self;
+    ctx->m_glPixelStorei_enc(ctx, param, value);
+    assert(ctx->m_state != NULL);
+    ctx->m_state->setPixelStore(param, value);
+}
+
+
+void GL2Encoder::s_glBindBuffer(void *self, GLenum target, GLuint id)
+{
+    GL2Encoder *ctx = (GL2Encoder *) self;
+    assert(ctx->m_state != NULL);
+    ctx->m_state->bindBuffer(target, id);
+    // TODO set error state if needed;
+    ctx->m_glBindBuffer_enc(self, target, id);
+}
+
+void GL2Encoder::s_glBufferData(void * self, GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage)
+{
+    GL2Encoder *ctx = (GL2Encoder *) self;
+    GLuint bufferId = ctx->m_state->getBuffer(target);
+    SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION);
+    SET_ERROR_IF(size<0, GL_INVALID_VALUE);
+
+    ctx->m_shared->updateBufferData(bufferId, size, (void*)data);
+    ctx->m_glBufferData_enc(self, target, size, data, usage);
+}
+
+void GL2Encoder::s_glBufferSubData(void * self, GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data)
+{
+    GL2Encoder *ctx = (GL2Encoder *) self;
+    GLuint bufferId = ctx->m_state->getBuffer(target);
+    SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION);
+
+    GLenum res = ctx->m_shared->subUpdateBufferData(bufferId, offset, size, (void*)data);
+    SET_ERROR_IF(res, res);
+
+    ctx->m_glBufferSubData_enc(self, target, offset, size, data);
+}
+
+void GL2Encoder::s_glDeleteBuffers(void * self, GLsizei n, const GLuint * buffers)
+{
+    GL2Encoder *ctx = (GL2Encoder *) self;
+    SET_ERROR_IF(n<0, GL_INVALID_VALUE);
+    for (int i=0; i<n; i++) {
+        ctx->m_shared->deleteBufferData(buffers[i]);
+        ctx->m_glDeleteBuffers_enc(self,1,&buffers[i]);
+    }
+}
+
+void GL2Encoder::s_glVertexAtrribPointer(void *self, GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid * ptr)
+{
+    GL2Encoder *ctx = (GL2Encoder *)self;
+    assert(ctx->m_state != NULL);
+    ctx->m_state->setState(indx, size, type, normalized, stride, ptr);
+}
+
+void GL2Encoder::s_glGetIntegerv(void *self, GLenum param, GLint *ptr)
+{
+    GL2Encoder *ctx = (GL2Encoder *) self;
+    assert(ctx->m_state != NULL);
+    GLClientState* state = ctx->m_state;
+
+    switch (param) {
+    case GL_NUM_SHADER_BINARY_FORMATS:
+        *ptr = 0;
+        break;
+    case GL_SHADER_BINARY_FORMATS:
+        // do nothing
+        break;
+
+    case GL_COMPRESSED_TEXTURE_FORMATS: {
+        GLint *compressedTextureFormats = ctx->getCompressedTextureFormats();
+        if (ctx->m_num_compressedTextureFormats > 0 &&
+                compressedTextureFormats != NULL) {
+            memcpy(ptr, compressedTextureFormats,
+                    ctx->m_num_compressedTextureFormats * sizeof(GLint));
+        }
+        break;
+    }
+
+    case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
+    case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
+    case GL_MAX_TEXTURE_IMAGE_UNITS:
+        ctx->m_glGetIntegerv_enc(self, param, ptr);
+        *ptr = MIN(*ptr, GLClientState::MAX_TEXTURE_UNITS);
+        break;
+
+    case GL_TEXTURE_BINDING_2D:
+        *ptr = state->getBoundTexture(GL_TEXTURE_2D);
+        break;
+    case GL_TEXTURE_BINDING_EXTERNAL_OES:
+        *ptr = state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES);
+        break;
+
+    default:
+        if (!ctx->m_state->getClientStateParameter<GLint>(param, ptr)) {
+            ctx->m_glGetIntegerv_enc(self, param, ptr);
+        }
+        break;
+    }
+}
+
+
+void GL2Encoder::s_glGetFloatv(void *self, GLenum param, GLfloat *ptr)
+{
+    GL2Encoder *ctx = (GL2Encoder *)self;
+    assert(ctx->m_state != NULL);
+    GLClientState* state = ctx->m_state;
+
+    switch (param) {
+    case GL_NUM_SHADER_BINARY_FORMATS:
+        *ptr = 0;
+        break;
+    case GL_SHADER_BINARY_FORMATS:
+        // do nothing
+        break;
+
+    case GL_COMPRESSED_TEXTURE_FORMATS: {
+        GLint *compressedTextureFormats = ctx->getCompressedTextureFormats();
+        if (ctx->m_num_compressedTextureFormats > 0 &&
+                compressedTextureFormats != NULL) {
+            for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) {
+                ptr[i] = (GLfloat) compressedTextureFormats[i];
+            }
+        }
+        break;
+    }
+
+    case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
+    case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
+    case GL_MAX_TEXTURE_IMAGE_UNITS:
+        ctx->m_glGetFloatv_enc(self, param, ptr);
+        *ptr = MIN(*ptr, (GLfloat)GLClientState::MAX_TEXTURE_UNITS);
+        break;
+
+    case GL_TEXTURE_BINDING_2D:
+        *ptr = (GLfloat)state->getBoundTexture(GL_TEXTURE_2D);
+        break;
+    case GL_TEXTURE_BINDING_EXTERNAL_OES:
+        *ptr = (GLfloat)state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES);
+        break;
+
+    default:
+        if (!ctx->m_state->getClientStateParameter<GLfloat>(param, ptr)) {
+            ctx->m_glGetFloatv_enc(self, param, ptr);
+        }
+        break;
+    }
+}
+
+
+void GL2Encoder::s_glGetBooleanv(void *self, GLenum param, GLboolean *ptr)
+{
+    GL2Encoder *ctx = (GL2Encoder *)self;
+    assert(ctx->m_state != NULL);
+    GLClientState* state = ctx->m_state;
+
+    switch (param) {
+    case GL_NUM_SHADER_BINARY_FORMATS:
+        *ptr = GL_FALSE;
+        break;
+    case GL_SHADER_BINARY_FORMATS:
+        // do nothing
+        break;
+
+    case GL_COMPRESSED_TEXTURE_FORMATS: {
+        GLint *compressedTextureFormats = ctx->getCompressedTextureFormats();
+        if (ctx->m_num_compressedTextureFormats > 0 &&
+                compressedTextureFormats != NULL) {
+            for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) {
+                ptr[i] = compressedTextureFormats[i] != 0 ? GL_TRUE : GL_FALSE;
+            }
+        }
+        break;
+    }
+
+    case GL_TEXTURE_BINDING_2D:
+        *ptr = state->getBoundTexture(GL_TEXTURE_2D) != 0 ? GL_TRUE : GL_FALSE;
+        break;
+    case GL_TEXTURE_BINDING_EXTERNAL_OES:
+        *ptr = state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES) != 0
+                ? GL_TRUE : GL_FALSE;
+        break;
+
+    default:
+        if (!ctx->m_state->getClientStateParameter<GLboolean>(param, ptr)) {
+            ctx->m_glGetBooleanv_enc(self, param, ptr);
+        }
+        break;
+    }
+}
+
+
+void GL2Encoder::s_glEnableVertexAttribArray(void *self, GLuint index)
+{
+    GL2Encoder *ctx = (GL2Encoder *)self;
+    assert(ctx->m_state);
+    ctx->m_state->enable(index, 1);
+}
+
+void GL2Encoder::s_glDisableVertexAttribArray(void *self, GLuint index)
+{
+    GL2Encoder *ctx = (GL2Encoder *)self;
+    assert(ctx->m_state);
+    ctx->m_state->enable(index, 0);
+}
+
+
+void GL2Encoder::s_glGetVertexAttribiv(void *self, GLuint index, GLenum pname, GLint *params)
+{
+    GL2Encoder *ctx = (GL2Encoder *)self;
+    assert(ctx->m_state);
+
+    if (!ctx->m_state->getVertexAttribParameter<GLint>(index, pname, params)) {
+        ctx->m_glGetVertexAttribiv_enc(self, index, pname, params);
+    }
+}
+
+void GL2Encoder::s_glGetVertexAttribfv(void *self, GLuint index, GLenum pname, GLfloat *params)
+{
+    GL2Encoder *ctx = (GL2Encoder *)self;
+    assert(ctx->m_state);
+
+    if (!ctx->m_state->getVertexAttribParameter<GLfloat>(index, pname, params)) {
+        ctx->m_glGetVertexAttribfv_enc(self, index, pname, params);
+    }
+}
+
+void GL2Encoder::s_glGetVertexAttribPointerv(void *self, GLuint index, GLenum pname, GLvoid **pointer)
+{
+    GL2Encoder *ctx = (GL2Encoder *)self;
+    if (ctx->m_state == NULL) return;
+
+    const GLClientState::VertexAttribState *va_state = ctx->m_state->getState(index);
+    if (va_state != NULL) {
+        *pointer = va_state->data;
+    }
+}
+
+
+void GL2Encoder::sendVertexAttributes(GLint first, GLsizei count)
+{
+    assert(m_state);
+
+    for (int i = 0; i < m_state->nLocations(); i++) {
+        bool enableDirty;
+        const GLClientState::VertexAttribState *state = m_state->getStateAndEnableDirty(i, &enableDirty);
+
+        if (!state) {
+            continue;
+        }
+
+        if (!enableDirty && !state->enabled) {
+            continue;
+        }
+
+
+        if (state->enabled) {
+            m_glEnableVertexAttribArray_enc(this, i);
+
+            unsigned int datalen = state->elementSize * count;
+            int stride = state->stride == 0 ? state->elementSize : state->stride;
+            int firstIndex = stride * first;
+
+            if (state->bufferObject == 0) {
+                this->glVertexAttribPointerData(this, i, state->size, state->type, state->normalized, state->stride,
+                                                (unsigned char *)state->data + firstIndex, datalen);
+            } else {
+                this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, state->bufferObject);
+                this->glVertexAttribPointerOffset(this, i, state->size, state->type, state->normalized, state->stride,
+                                                  (GLuint) state->data + firstIndex);
+                this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, m_state->currentArrayVbo());
+            }
+        } else {
+            this->m_glDisableVertexAttribArray_enc(this, i);
+        }
+    }
+}
+
+void GL2Encoder::s_glDrawArrays(void *self, GLenum mode, GLint first, GLsizei count)
+{
+    GL2Encoder *ctx = (GL2Encoder *)self;
+    ctx->sendVertexAttributes(first, count);
+    ctx->m_glDrawArrays_enc(ctx, mode, 0, count);
+}
+
+
+void GL2Encoder::s_glDrawElements(void *self, GLenum mode, GLsizei count, GLenum type, const void *indices)
+{
+
+    GL2Encoder *ctx = (GL2Encoder *)self;
+    assert(ctx->m_state != NULL);
+    SET_ERROR_IF(count<0, GL_INVALID_VALUE);
+
+    bool has_immediate_arrays = false;
+    bool has_indirect_arrays = false;
+    int nLocations = ctx->m_state->nLocations();
+
+    for (int i = 0; i < nLocations; i++) {
+        const GLClientState::VertexAttribState *state = ctx->m_state->getState(i);
+        if (state->enabled) {
+            if (state->bufferObject != 0) {
+                has_indirect_arrays = true;
+            } else {
+                has_immediate_arrays = true;
+            }
+        }
+    }
+
+    if (!has_immediate_arrays && !has_indirect_arrays) {
+        ALOGE("glDrawElements: no data bound to the command - ignoring\n");
+        return;
+    }
+
+    bool adjustIndices = true;
+    if (ctx->m_state->currentIndexVbo() != 0) {
+        if (!has_immediate_arrays) {
+            ctx->sendVertexAttributes(0, count);
+            ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo());
+            ctx->glDrawElementsOffset(ctx, mode, count, type, (GLuint)indices);
+            adjustIndices = false;
+        } else {
+            BufferData * buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
+            ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, 0);
+            indices = (void*)((GLintptr)buf->m_fixedBuffer.ptr() + (GLintptr)indices);
+        }
+    }
+    if (adjustIndices) {
+        void *adjustedIndices = (void*)indices;
+        int minIndex = 0, maxIndex = 0;
+
+        switch(type) {
+        case GL_BYTE:
+        case GL_UNSIGNED_BYTE:
+            GLUtils::minmax<unsigned char>((unsigned char *)indices, count, &minIndex, &maxIndex);
+            if (minIndex != 0) {
+                adjustedIndices =  ctx->m_fixedBuffer.alloc(glSizeof(type) * count);
+                GLUtils::shiftIndices<unsigned char>((unsigned char *)indices,
+                                                 (unsigned char *)adjustedIndices,
+                                                 count, -minIndex);
+            }
+            break;
+        case GL_SHORT:
+        case GL_UNSIGNED_SHORT:
+            GLUtils::minmax<unsigned short>((unsigned short *)indices, count, &minIndex, &maxIndex);
+            if (minIndex != 0) {
+                adjustedIndices = ctx->m_fixedBuffer.alloc(glSizeof(type) * count);
+                GLUtils::shiftIndices<unsigned short>((unsigned short *)indices,
+                                                  (unsigned short *)adjustedIndices,
+                                                  count, -minIndex);
+            }
+            break;
+        default:
+            ALOGE("unsupported index buffer type %d\n", type);
+        }
+        if (has_indirect_arrays || 1) {
+            ctx->sendVertexAttributes(minIndex, maxIndex - minIndex + 1);
+            ctx->glDrawElementsData(ctx, mode, count, type, adjustedIndices,
+                                    count * glSizeof(type));
+            // XXX - OPTIMIZATION (see the other else branch) should be implemented
+            if(!has_indirect_arrays) {
+                //ALOGD("unoptimized drawelements !!!\n");
+            }
+        } else {
+            // we are all direct arrays and immidate mode index array -
+            // rebuild the arrays and the index array;
+            ALOGE("glDrawElements: direct index & direct buffer data - will be implemented in later versions;\n");
+        }
+    }
+}
+
+
+GLint * GL2Encoder::getCompressedTextureFormats()
+{
+    if (m_compressedTextureFormats == NULL) {
+        this->glGetIntegerv(this, GL_NUM_COMPRESSED_TEXTURE_FORMATS,
+                            &m_num_compressedTextureFormats);
+        if (m_num_compressedTextureFormats > 0) {
+            // get number of texture formats;
+            m_compressedTextureFormats = new GLint[m_num_compressedTextureFormats];
+            this->glGetCompressedTextureFormats(this, m_num_compressedTextureFormats, m_compressedTextureFormats);
+        }
+    }
+    return m_compressedTextureFormats;
+}
+
+// Replace uses of samplerExternalOES with sampler2D, recording the names of
+// modified shaders in data. Also remove
+//   #extension GL_OES_EGL_image_external : require
+// statements.
+//
+// This implementation assumes the input has already been pre-processed. If not,
+// a few cases will be mishandled:
+//
+// 1. "mySampler" will be incorrectly recorded as being a samplerExternalOES in
+//    the following code:
+//      #if 1
+//      uniform sampler2D mySampler;
+//      #else
+//      uniform samplerExternalOES mySampler;
+//      #endif
+//
+// 2. Comments that look like sampler declarations will be incorrectly modified
+//    and recorded:
+//      // samplerExternalOES hahaFooledYou
+//
+// 3. However, GLSL ES does not have a concatentation operator, so things like
+//    this (valid in C) are invalid and not a problem:
+//      #define SAMPLER(TYPE, NAME) uniform sampler#TYPE NAME
+//      SAMPLER(ExternalOES, mySampler);
+//
+static bool replaceSamplerExternalWith2D(char* const str, ShaderData* const data)
+{
+    static const char STR_HASH_EXTENSION[] = "#extension";
+    static const char STR_GL_OES_EGL_IMAGE_EXTERNAL[] = "GL_OES_EGL_image_external";
+    static const char STR_SAMPLER_EXTERNAL_OES[] = "samplerExternalOES";
+    static const char STR_SAMPLER2D_SPACE[]      = "sampler2D         ";
+
+    // -- overwrite all "#extension GL_OES_EGL_image_external : xxx" statements
+    char* c = str;
+    while ((c = strstr(c, STR_HASH_EXTENSION))) {
+        char* start = c;
+        c += sizeof(STR_HASH_EXTENSION)-1;
+        while (isspace(*c) && *c != '\0') {
+            c++;
+        }
+        if (strncmp(c, STR_GL_OES_EGL_IMAGE_EXTERNAL,
+                sizeof(STR_GL_OES_EGL_IMAGE_EXTERNAL)-1) == 0)
+        {
+            // #extension statements are terminated by end of line
+            c = start;
+            while (*c != '\0' && *c != '\r' && *c != '\n') {
+                *c++ = ' ';
+            }
+        }
+    }
+
+    // -- replace "samplerExternalOES" with "sampler2D" and record name
+    c = str;
+    while ((c = strstr(c, STR_SAMPLER_EXTERNAL_OES))) {
+        // Make sure "samplerExternalOES" isn't a substring of a larger token
+        if (c == str || !isspace(*(c-1))) {
+            c++;
+            continue;
+        }
+        char* sampler_start = c;
+        c += sizeof(STR_SAMPLER_EXTERNAL_OES)-1;
+        if (!isspace(*c) && *c != '\0') {
+            continue;
+        }
+
+        // capture sampler name
+        while (isspace(*c) && *c != '\0') {
+            c++;
+        }
+        if (!isalpha(*c) && *c != '_') {
+            // not an identifier
+            return false;
+        }
+        char* name_start = c;
+        do {
+            c++;
+        } while (isalnum(*c) || *c == '_');
+        data->samplerExternalNames.push_back(
+                android::String8(name_start, c - name_start));
+
+        // memcpy instead of strcpy since we don't want the NUL terminator
+        memcpy(sampler_start, STR_SAMPLER2D_SPACE, sizeof(STR_SAMPLER2D_SPACE)-1);
+    }
+
+    return true;
+}
+
+void GL2Encoder::s_glShaderSource(void *self, GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length)
+{
+    GL2Encoder* ctx = (GL2Encoder*)self;
+    ShaderData* shaderData = ctx->m_shared->getShaderData(shader);
+    SET_ERROR_IF(!shaderData, GL_INVALID_VALUE);
+
+    int len = glUtilsCalcShaderSourceLen((char**)string, (GLint*)length, count);
+    char *str = new char[len + 1];
+    glUtilsPackStrings(str, (char**)string, (GLint*)length, count);
+
+    // TODO: pre-process str before calling replaceSamplerExternalWith2D().
+    // Perhaps we can borrow Mesa's pre-processor?
+
+    if (!replaceSamplerExternalWith2D(str, shaderData)) {
+        delete str;
+        ctx->setError(GL_OUT_OF_MEMORY);
+        return;
+    }
+
+    ctx->glShaderString(ctx, shader, str, len + 1);
+    delete str;
+}
+
+void GL2Encoder::s_glFinish(void *self)
+{
+    GL2Encoder *ctx = (GL2Encoder *)self;
+    ctx->glFinishRoundTrip(self);
+}
+
+void GL2Encoder::s_glLinkProgram(void * self, GLuint program)
+{
+    GL2Encoder *ctx = (GL2Encoder *)self;
+    ctx->m_glLinkProgram_enc(self, program);
+
+    GLint linkStatus = 0;
+    ctx->glGetProgramiv(self,program,GL_LINK_STATUS,&linkStatus);
+    if (!linkStatus)
+        return;
+
+    //get number of active uniforms in the program
+    GLint numUniforms=0;
+    ctx->glGetProgramiv(self, program, GL_ACTIVE_UNIFORMS, &numUniforms);
+    ctx->m_shared->initProgramData(program,numUniforms);
+
+    //get the length of the longest uniform name
+    GLint maxLength=0;
+    ctx->glGetProgramiv(self, program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLength);
+
+    GLint size;
+    GLenum type;
+    GLchar *name = new GLchar[maxLength+1];
+    GLint location;
+    //for each active uniform, get its size and starting location.
+    for (GLint i=0 ; i<numUniforms ; ++i)
+    {
+        ctx->glGetActiveUniform(self, program, i, maxLength, NULL, &size, &type, name);
+        location = ctx->m_glGetUniformLocation_enc(self, program, name);
+        ctx->m_shared->setProgramIndexInfo(program, i, location, size, type, name);
+    }
+    ctx->m_shared->setupLocationShiftWAR(program);
+
+    delete[] name;
+}
+
+void GL2Encoder::s_glDeleteProgram(void *self, GLuint program)
+{
+    GL2Encoder *ctx = (GL2Encoder*)self;
+    ctx->m_glDeleteProgram_enc(self, program);
+
+    ctx->m_shared->deleteProgramData(program);
+}
+
+void GL2Encoder::s_glGetUniformiv(void *self, GLuint program, GLint location, GLint* params)
+{
+    GL2Encoder *ctx = (GL2Encoder*)self;
+    SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_VALUE);
+    SET_ERROR_IF(!ctx->m_shared->isProgramInitialized(program), GL_INVALID_OPERATION);
+    GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
+    SET_ERROR_IF(ctx->m_shared->getProgramUniformType(program,hostLoc)==0, GL_INVALID_OPERATION);
+    ctx->m_glGetUniformiv_enc(self, program, hostLoc, params);
+}
+void GL2Encoder::s_glGetUniformfv(void *self, GLuint program, GLint location, GLfloat* params)
+{
+    GL2Encoder *ctx = (GL2Encoder*)self;
+    SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_VALUE);
+    SET_ERROR_IF(!ctx->m_shared->isProgramInitialized(program), GL_INVALID_OPERATION);
+    GLint hostLoc = ctx->m_shared->locationWARAppToHost(program,location);
+    SET_ERROR_IF(ctx->m_shared->getProgramUniformType(program,hostLoc)==0, GL_INVALID_OPERATION);
+    ctx->m_glGetUniformfv_enc(self, program, hostLoc, params);
+}
+
+GLuint GL2Encoder::s_glCreateProgram(void * self)
+{
+    GL2Encoder *ctx = (GL2Encoder*)self;
+    GLuint program = ctx->m_glCreateProgram_enc(self);
+    if (program!=0)
+        ctx->m_shared->addProgramData(program);
+    return program;
+}
+
+GLuint GL2Encoder::s_glCreateShader(void *self, GLenum shaderType)
+{
+    GL2Encoder *ctx = (GL2Encoder*)self;
+    GLuint shader = ctx->m_glCreateShader_enc(self, shaderType);
+    if (shader != 0) {
+        if (!ctx->m_shared->addShaderData(shader)) {
+            ctx->m_glDeleteShader_enc(self, shader);
+            return 0;
+        }
+    }
+    return shader;
+}
+
+void GL2Encoder::s_glDeleteShader(void *self, GLenum shader)
+{
+    GL2Encoder *ctx = (GL2Encoder*)self;
+    ctx->m_glDeleteShader_enc(self,shader);
+    ctx->m_shared->unrefShaderData(shader);
+}
+
+void GL2Encoder::s_glAttachShader(void *self, GLuint program, GLuint shader)
+{
+    GL2Encoder *ctx = (GL2Encoder*)self;
+    ctx->m_glAttachShader_enc(self, program, shader);
+    ctx->m_shared->attachShader(program, shader);
+}
+
+void GL2Encoder::s_glDetachShader(void *self, GLuint program, GLuint shader)
+{
+    GL2Encoder *ctx = (GL2Encoder*)self;
+    ctx->m_glDetachShader_enc(self, program, shader);
+    ctx->m_shared->detachShader(program, shader);
+}
+
+int GL2Encoder::s_glGetUniformLocation(void *self, GLuint program, const GLchar *name)
+{
+    if (!name) return -1;
+
+    GL2Encoder *ctx = (GL2Encoder*)self;
+
+    // if we need the uniform location WAR
+    // parse array index from the end of the name string
+    int arrIndex = 0;
+    bool needLocationWAR = ctx->m_shared->needUniformLocationWAR(program);
+    if (needLocationWAR) {
+        int namelen = strlen(name);
+        if (name[namelen-1] == ']') {
+            char *brace = strrchr(name,'[');
+            if (!brace || sscanf(brace+1,"%d",&arrIndex) != 1) {
+                return -1;
+            }
+
+        }
+    }
+
+    int hostLoc = ctx->m_glGetUniformLocation_enc(self, program, name);
+    if (hostLoc >= 0 && needLocationWAR) {
+        return ctx->m_shared->locationWARHostToApp(program, hostLoc, arrIndex);
+    }
+    return hostLoc;
+}
+
+bool GL2Encoder::updateHostTexture2DBinding(GLenum texUnit, GLenum newTarget)
+{
+    if (newTarget != GL_TEXTURE_2D && newTarget != GL_TEXTURE_EXTERNAL_OES)
+        return false;
+
+    m_state->setActiveTextureUnit(texUnit);
+
+    GLenum oldTarget = m_state->getPriorityEnabledTarget(GL_TEXTURE_2D);
+    if (newTarget != oldTarget) {
+        if (newTarget == GL_TEXTURE_EXTERNAL_OES) {
+            m_state->disableTextureTarget(GL_TEXTURE_2D);
+            m_state->enableTextureTarget(GL_TEXTURE_EXTERNAL_OES);
+        } else {
+            m_state->disableTextureTarget(GL_TEXTURE_EXTERNAL_OES);
+            m_state->enableTextureTarget(GL_TEXTURE_2D);
+        }
+        m_glActiveTexture_enc(this, texUnit);
+        m_glBindTexture_enc(this, GL_TEXTURE_2D,
+                m_state->getBoundTexture(newTarget));
+        return true;
+    }
+
+    return false;
+}
+
+void GL2Encoder::s_glUseProgram(void *self, GLuint program)
+{
+    GL2Encoder *ctx = (GL2Encoder*)self;
+    GLClientState* state = ctx->m_state;
+    GLSharedGroupPtr shared = ctx->m_shared;
+
+    ctx->m_glUseProgram_enc(self, program);
+    ctx->m_state->setCurrentProgram(program);
+
+    GLenum origActiveTexture = state->getActiveTextureUnit();
+    GLenum hostActiveTexture = origActiveTexture;
+    GLint samplerIdx = -1;
+    GLint samplerVal;
+    GLenum samplerTarget;
+    while ((samplerIdx = shared->getNextSamplerUniform(program, samplerIdx, &samplerVal, &samplerTarget)) != -1) {
+        if (samplerVal < 0 || samplerVal >= GLClientState::MAX_TEXTURE_UNITS)
+            continue;
+        if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + samplerVal,
+                samplerTarget))
+        {
+            hostActiveTexture = GL_TEXTURE0 + samplerVal;
+        }
+    }
+    state->setActiveTextureUnit(origActiveTexture);
+    if (hostActiveTexture != origActiveTexture) {
+        ctx->m_glActiveTexture_enc(self, origActiveTexture);
+    }
+}
+
+void GL2Encoder::s_glUniform1f(void *self , GLint location, GLfloat x)
+{
+    GL2Encoder *ctx = (GL2Encoder*)self;
+    GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+    ctx->m_glUniform1f_enc(self, hostLoc, x);
+}
+
+void GL2Encoder::s_glUniform1fv(void *self , GLint location, GLsizei count, const GLfloat* v)
+{
+    GL2Encoder *ctx = (GL2Encoder*)self;
+    GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+    ctx->m_glUniform1fv_enc(self, hostLoc, count, v);
+}
+
+void GL2Encoder::s_glUniform1i(void *self , GLint location, GLint x)
+{
+    GL2Encoder *ctx = (GL2Encoder*)self;
+    GLClientState* state = ctx->m_state;
+    GLSharedGroupPtr shared = ctx->m_shared;
+
+    GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+    ctx->m_glUniform1i_enc(self, hostLoc, x);
+
+    GLenum target;
+    if (shared->setSamplerUniform(state->currentProgram(), location, x, &target)) {
+        GLenum origActiveTexture = state->getActiveTextureUnit();
+        if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + x, target)) {
+            ctx->m_glActiveTexture_enc(self, origActiveTexture);
+        }
+        state->setActiveTextureUnit(origActiveTexture);
+    }
+}
+
+void GL2Encoder::s_glUniform1iv(void *self , GLint location, GLsizei count, const GLint* v)
+{
+    GL2Encoder *ctx = (GL2Encoder*)self;
+    GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+    ctx->m_glUniform1iv_enc(self, hostLoc, count, v);
+}
+
+void GL2Encoder::s_glUniform2f(void *self , GLint location, GLfloat x, GLfloat y)
+{
+    GL2Encoder *ctx = (GL2Encoder*)self;
+    GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+    ctx->m_glUniform2f_enc(self, hostLoc, x, y);
+}
+
+void GL2Encoder::s_glUniform2fv(void *self , GLint location, GLsizei count, const GLfloat* v)
+{
+    GL2Encoder *ctx = (GL2Encoder*)self;
+    GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+    ctx->m_glUniform2fv_enc(self, hostLoc, count, v);
+}
+
+void GL2Encoder::s_glUniform2i(void *self , GLint location, GLint x, GLint y)
+{
+    GL2Encoder *ctx = (GL2Encoder*)self;
+    GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+    ctx->m_glUniform2i_enc(self, hostLoc, x, y);
+}
+
+void GL2Encoder::s_glUniform2iv(void *self , GLint location, GLsizei count, const GLint* v)
+{
+    GL2Encoder *ctx = (GL2Encoder*)self;
+    GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+    ctx->m_glUniform2iv_enc(self, hostLoc, count, v);
+}
+
+void GL2Encoder::s_glUniform3f(void *self , GLint location, GLfloat x, GLfloat y, GLfloat z)
+{
+    GL2Encoder *ctx = (GL2Encoder*)self;
+    GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+    ctx->m_glUniform3f_enc(self, hostLoc, x, y, z);
+}
+
+void GL2Encoder::s_glUniform3fv(void *self , GLint location, GLsizei count, const GLfloat* v)
+{
+    GL2Encoder *ctx = (GL2Encoder*)self;
+    GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+    ctx->m_glUniform3fv_enc(self, hostLoc, count, v);
+}
+
+void GL2Encoder::s_glUniform3i(void *self , GLint location, GLint x, GLint y, GLint z)
+{
+    GL2Encoder *ctx = (GL2Encoder*)self;
+    GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+    ctx->m_glUniform3i_enc(self, hostLoc, x, y, z);
+}
+
+void GL2Encoder::s_glUniform3iv(void *self , GLint location, GLsizei count, const GLint* v)
+{
+    GL2Encoder *ctx = (GL2Encoder*)self;
+    GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+    ctx->m_glUniform3iv_enc(self, hostLoc, count, v);
+}
+
+void GL2Encoder::s_glUniform4f(void *self , GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+    GL2Encoder *ctx = (GL2Encoder*)self;
+    GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+    ctx->m_glUniform4f_enc(self, hostLoc, x, y, z, w);
+}
+
+void GL2Encoder::s_glUniform4fv(void *self , GLint location, GLsizei count, const GLfloat* v)
+{
+    GL2Encoder *ctx = (GL2Encoder*)self;
+    GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+    ctx->m_glUniform4fv_enc(self, hostLoc, count, v);
+}
+
+void GL2Encoder::s_glUniform4i(void *self , GLint location, GLint x, GLint y, GLint z, GLint w)
+{
+    GL2Encoder *ctx = (GL2Encoder*)self;
+    GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+    ctx->m_glUniform4i_enc(self, hostLoc, x, y, z, w);
+}
+
+void GL2Encoder::s_glUniform4iv(void *self , GLint location, GLsizei count, const GLint* v)
+{
+    GL2Encoder *ctx = (GL2Encoder*)self;
+    GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+    ctx->m_glUniform4iv_enc(self, hostLoc, count, v);
+}
+
+void GL2Encoder::s_glUniformMatrix2fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+    GL2Encoder *ctx = (GL2Encoder*)self;
+    GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+    ctx->m_glUniformMatrix2fv_enc(self, hostLoc, count, transpose, value);
+}
+
+void GL2Encoder::s_glUniformMatrix3fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+    GL2Encoder *ctx = (GL2Encoder*)self;
+    GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+    ctx->m_glUniformMatrix3fv_enc(self, hostLoc, count, transpose, value);
+}
+
+void GL2Encoder::s_glUniformMatrix4fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+    GL2Encoder *ctx = (GL2Encoder*)self;
+    GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+    ctx->m_glUniformMatrix4fv_enc(self, hostLoc, count, transpose, value);
+}
+
+void GL2Encoder::s_glActiveTexture(void* self, GLenum texture)
+{
+    GL2Encoder* ctx = (GL2Encoder*)self;
+    GLClientState* state = ctx->m_state;
+    GLenum err;
+
+    SET_ERROR_IF((err = state->setActiveTextureUnit(texture)) != GL_NO_ERROR, err);
+
+    ctx->m_glActiveTexture_enc(ctx, texture);
+}
+
+void GL2Encoder::s_glBindTexture(void* self, GLenum target, GLuint texture)
+{
+    GL2Encoder* ctx = (GL2Encoder*)self;
+    GLClientState* state = ctx->m_state;
+    GLenum err;
+    GLboolean firstUse;
+
+    SET_ERROR_IF((err = state->bindTexture(target, texture, &firstUse)) != GL_NO_ERROR, err);
+
+    if (target != GL_TEXTURE_2D && target != GL_TEXTURE_EXTERNAL_OES) {
+        ctx->m_glBindTexture_enc(ctx, target, texture);
+        return;
+    }
+
+    GLenum priorityTarget = state->getPriorityEnabledTarget(GL_TEXTURE_2D);
+
+    if (target == GL_TEXTURE_EXTERNAL_OES && firstUse) {
+        ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, texture);
+        ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
+                GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+        ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
+                GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+        ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D,
+                GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+        if (target != priorityTarget) {
+            ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D,
+                    state->getBoundTexture(GL_TEXTURE_2D));
+        }
+    }
+
+    if (target == priorityTarget) {
+        ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, texture);
+    }
+}
+
+void GL2Encoder::s_glDeleteTextures(void* self, GLsizei n, const GLuint* textures)
+{
+    GL2Encoder* ctx = (GL2Encoder*)self;
+    GLClientState* state = ctx->m_state;
+
+    state->deleteTextures(n, textures);
+    ctx->m_glDeleteTextures_enc(ctx, n, textures);
+}
+
+void GL2Encoder::s_glGetTexParameterfv(void* self,
+        GLenum target, GLenum pname, GLfloat* params)
+{
+    GL2Encoder* ctx = (GL2Encoder*)self;
+    const GLClientState* state = ctx->m_state;
+
+    if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
+        ctx->override2DTextureTarget(target);
+        ctx->m_glGetTexParameterfv_enc(ctx, GL_TEXTURE_2D, pname, params);
+        ctx->restore2DTextureTarget();
+    } else {
+        ctx->m_glGetTexParameterfv_enc(ctx, target, pname, params);
+    }
+}
+
+void GL2Encoder::s_glGetTexParameteriv(void* self,
+        GLenum target, GLenum pname, GLint* params)
+{
+    GL2Encoder* ctx = (GL2Encoder*)self;
+    const GLClientState* state = ctx->m_state;
+
+    switch (pname) {
+    case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
+        *params = 1;
+        break;
+
+    default:
+        if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
+            ctx->override2DTextureTarget(target);
+            ctx->m_glGetTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params);
+            ctx->restore2DTextureTarget();
+        } else {
+            ctx->m_glGetTexParameteriv_enc(ctx, target, pname, params);
+        }
+        break;
+    }
+}
+
+static bool isValidTextureExternalParam(GLenum pname, GLenum param)
+{
+    switch (pname) {
+    case GL_TEXTURE_MIN_FILTER:
+    case GL_TEXTURE_MAG_FILTER:
+        return param == GL_NEAREST || param == GL_LINEAR;
+
+    case GL_TEXTURE_WRAP_S:
+    case GL_TEXTURE_WRAP_T:
+        return param == GL_CLAMP_TO_EDGE;
+
+    default:
+        return true;
+    }
+}
+
+void GL2Encoder::s_glTexParameterf(void* self,
+        GLenum target, GLenum pname, GLfloat param)
+{
+    GL2Encoder* ctx = (GL2Encoder*)self;
+    const GLClientState* state = ctx->m_state;
+
+    SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
+            !isValidTextureExternalParam(pname, (GLenum)param)),
+            GL_INVALID_ENUM);
+
+    if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
+        ctx->override2DTextureTarget(target);
+        ctx->m_glTexParameterf_enc(ctx, GL_TEXTURE_2D, pname, param);
+        ctx->restore2DTextureTarget();
+    } else {
+        ctx->m_glTexParameterf_enc(ctx, target, pname, param);
+    }
+}
+
+void GL2Encoder::s_glTexParameterfv(void* self,
+        GLenum target, GLenum pname, const GLfloat* params)
+{
+    GL2Encoder* ctx = (GL2Encoder*)self;
+    const GLClientState* state = ctx->m_state;
+
+    SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
+            !isValidTextureExternalParam(pname, (GLenum)params[0])),
+            GL_INVALID_ENUM);
+
+    if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
+        ctx->override2DTextureTarget(target);
+        ctx->m_glTexParameterfv_enc(ctx, GL_TEXTURE_2D, pname, params);
+        ctx->restore2DTextureTarget();
+    } else {
+        ctx->m_glTexParameterfv_enc(ctx, target, pname, params);
+    }
+}
+
+void GL2Encoder::s_glTexParameteri(void* self,
+        GLenum target, GLenum pname, GLint param)
+{
+    GL2Encoder* ctx = (GL2Encoder*)self;
+    const GLClientState* state = ctx->m_state;
+
+    SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
+            !isValidTextureExternalParam(pname, (GLenum)param)),
+            GL_INVALID_ENUM);
+
+    if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
+        ctx->override2DTextureTarget(target);
+        ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D, pname, param);
+        ctx->restore2DTextureTarget();
+    } else {
+        ctx->m_glTexParameteri_enc(ctx, target, pname, param);
+    }
+}
+
+void GL2Encoder::s_glTexParameteriv(void* self,
+        GLenum target, GLenum pname, const GLint* params)
+{
+    GL2Encoder* ctx = (GL2Encoder*)self;
+    const GLClientState* state = ctx->m_state;
+
+    SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES &&
+            !isValidTextureExternalParam(pname, (GLenum)params[0])),
+            GL_INVALID_ENUM);
+
+    if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) {
+        ctx->override2DTextureTarget(target);
+        ctx->m_glTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params);
+        ctx->restore2DTextureTarget();
+    } else {
+        ctx->m_glTexParameteriv_enc(ctx, target, pname, params);
+    }
+}
+
+void GL2Encoder::override2DTextureTarget(GLenum target)
+{
+    if ((target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) &&
+        target != m_state->getPriorityEnabledTarget(GL_TEXTURE_2D)) {
+            m_glBindTexture_enc(this, GL_TEXTURE_2D,
+                    m_state->getBoundTexture(target));
+    }
+}
+
+void GL2Encoder::restore2DTextureTarget()
+{
+    GLenum priorityTarget = m_state->getPriorityEnabledTarget(GL_TEXTURE_2D);
+    m_glBindTexture_enc(this, GL_TEXTURE_2D,
+            m_state->getBoundTexture(priorityTarget));
+}
diff --git a/opengl/system/GLESv2_enc/GL2Encoder.h b/opengl/system/GLESv2_enc/GL2Encoder.h
new file mode 100644
index 0000000..c6506a9
--- /dev/null
+++ b/opengl/system/GLESv2_enc/GL2Encoder.h
@@ -0,0 +1,216 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#ifndef _GL2_ENCODER_H_
+#define _GL2_ENCODER_H_
+
+#include "gl2_enc.h"
+#include "GLClientState.h"
+#include "GLSharedGroup.h"
+#include "FixedBuffer.h"
+
+
+class GL2Encoder : public gl2_encoder_context_t {
+public:
+    GL2Encoder(IOStream *stream);
+    virtual ~GL2Encoder();
+    void setClientState(GLClientState *state) {
+        m_state = state;
+    }
+    void setSharedGroup(GLSharedGroupPtr shared){ m_shared = shared; }
+    const GLClientState *state() { return m_state; }
+    const GLSharedGroupPtr shared() { return m_shared; }
+    void flush() { m_stream->flush(); }
+
+    void setInitialized(){ m_initialized = true; };
+    bool isInitialized(){ return m_initialized; };
+
+    virtual void setError(GLenum error){ m_error = error; };
+    virtual GLenum getError() { return m_error; };
+
+    void override2DTextureTarget(GLenum target);
+    void restore2DTextureTarget();
+
+private:
+
+    bool    m_initialized;
+    GLClientState *m_state;
+    GLSharedGroupPtr m_shared;
+    GLenum  m_error;
+
+    GLint *m_compressedTextureFormats;
+    GLint m_num_compressedTextureFormats;
+    GLint *getCompressedTextureFormats();
+
+    FixedBuffer m_fixedBuffer;
+
+    void sendVertexAttributes(GLint first, GLsizei count);
+    bool updateHostTexture2DBinding(GLenum texUnit, GLenum newTarget);
+
+    glGetError_client_proc_t    m_glGetError_enc;
+    static GLenum s_glGetError(void * self);
+
+    glFlush_client_proc_t m_glFlush_enc;
+    static void s_glFlush(void * self);
+
+    glPixelStorei_client_proc_t m_glPixelStorei_enc;
+    static void s_glPixelStorei(void *self, GLenum param, GLint value);
+
+    glGetString_client_proc_t m_glGetString_enc;
+    static const GLubyte * s_glGetString(void *self, GLenum name);
+
+    glBindBuffer_client_proc_t m_glBindBuffer_enc;
+    static void s_glBindBuffer(void *self, GLenum target, GLuint id);
+
+
+    glBufferData_client_proc_t m_glBufferData_enc;
+    static void s_glBufferData(void *self, GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage);
+    glBufferSubData_client_proc_t m_glBufferSubData_enc;
+    static void s_glBufferSubData(void *self, GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data);
+    glDeleteBuffers_client_proc_t m_glDeleteBuffers_enc;
+    static void s_glDeleteBuffers(void *self, GLsizei n, const GLuint * buffers);
+
+    glDrawArrays_client_proc_t m_glDrawArrays_enc;
+    static void s_glDrawArrays(void *self, GLenum mode, GLint first, GLsizei count);
+
+    glDrawElements_client_proc_t m_glDrawElements_enc;
+    static void s_glDrawElements(void *self, GLenum mode, GLsizei count, GLenum type, const void *indices);
+
+
+    glGetIntegerv_client_proc_t m_glGetIntegerv_enc;
+    static void s_glGetIntegerv(void *self, GLenum pname, GLint *ptr);
+
+    glGetFloatv_client_proc_t m_glGetFloatv_enc;
+    static void s_glGetFloatv(void *self, GLenum pname, GLfloat *ptr);
+
+    glGetBooleanv_client_proc_t m_glGetBooleanv_enc;
+    static void s_glGetBooleanv(void *self, GLenum pname, GLboolean *ptr);
+
+    glVertexAttribPointer_client_proc_t m_glVertexAttribPointer_enc;
+    static void s_glVertexAtrribPointer(void *self, GLuint indx, GLint size, GLenum type,
+                                        GLboolean normalized, GLsizei stride, const GLvoid * ptr);
+
+    glEnableVertexAttribArray_client_proc_t m_glEnableVertexAttribArray_enc;
+    static void s_glEnableVertexAttribArray(void *self, GLuint index);
+
+    glDisableVertexAttribArray_client_proc_t m_glDisableVertexAttribArray_enc;
+    static void s_glDisableVertexAttribArray(void *self, GLuint index);
+
+    glGetVertexAttribiv_client_proc_t m_glGetVertexAttribiv_enc;
+    static void s_glGetVertexAttribiv(void *self, GLuint index, GLenum pname, GLint *params);
+
+    glGetVertexAttribfv_client_proc_t m_glGetVertexAttribfv_enc;
+    static void s_glGetVertexAttribfv(void *self, GLuint index, GLenum pname, GLfloat *params);
+
+    glGetVertexAttribPointerv_client_proc_t m_glGetVertexAttribPointerv;
+    static void s_glGetVertexAttribPointerv(void *self, GLuint index, GLenum pname, GLvoid **pointer);
+
+    static void s_glShaderSource(void *self, GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length);
+
+    static void s_glFinish(void *self);
+
+    glLinkProgram_client_proc_t m_glLinkProgram_enc;
+    static void s_glLinkProgram(void *self, GLuint program);
+
+    glDeleteProgram_client_proc_t m_glDeleteProgram_enc;
+    static void s_glDeleteProgram(void * self, GLuint program);
+
+    glGetUniformiv_client_proc_t m_glGetUniformiv_enc;
+    static void s_glGetUniformiv(void *self, GLuint program, GLint location , GLint *params);
+
+    glGetUniformfv_client_proc_t m_glGetUniformfv_enc;
+    static void s_glGetUniformfv(void *self, GLuint program, GLint location , GLfloat *params);
+
+    glCreateProgram_client_proc_t m_glCreateProgram_enc;
+    static GLuint s_glCreateProgram(void *self);
+
+    glCreateShader_client_proc_t m_glCreateShader_enc;
+    static GLuint s_glCreateShader(void *self, GLenum shaderType);
+
+    glDeleteShader_client_proc_t m_glDeleteShader_enc;
+    static void s_glDeleteShader(void *self, GLuint shader);
+
+    glAttachShader_client_proc_t m_glAttachShader_enc;
+    static void s_glAttachShader(void *self, GLuint program, GLuint shader);
+
+    glDetachShader_client_proc_t m_glDetachShader_enc;
+    static void s_glDetachShader(void *self, GLuint program, GLuint shader);
+
+    glGetUniformLocation_client_proc_t m_glGetUniformLocation_enc;
+    static int s_glGetUniformLocation(void *self, GLuint program, const GLchar *name);
+    glUseProgram_client_proc_t m_glUseProgram_enc;
+
+    glUniform1f_client_proc_t m_glUniform1f_enc;
+    glUniform1fv_client_proc_t m_glUniform1fv_enc;
+    glUniform1i_client_proc_t m_glUniform1i_enc;
+    glUniform1iv_client_proc_t m_glUniform1iv_enc;
+    glUniform2f_client_proc_t m_glUniform2f_enc;
+    glUniform2fv_client_proc_t m_glUniform2fv_enc;
+    glUniform2i_client_proc_t m_glUniform2i_enc;
+    glUniform2iv_client_proc_t m_glUniform2iv_enc;
+    glUniform3f_client_proc_t m_glUniform3f_enc;
+    glUniform3fv_client_proc_t m_glUniform3fv_enc;
+    glUniform3i_client_proc_t m_glUniform3i_enc;
+    glUniform3iv_client_proc_t m_glUniform3iv_enc;
+    glUniform4f_client_proc_t m_glUniform4f_enc;
+    glUniform4fv_client_proc_t m_glUniform4fv_enc;
+    glUniform4i_client_proc_t m_glUniform4i_enc;
+    glUniform4iv_client_proc_t m_glUniform4iv_enc;
+    glUniformMatrix2fv_client_proc_t m_glUniformMatrix2fv_enc;
+    glUniformMatrix3fv_client_proc_t m_glUniformMatrix3fv_enc;
+    glUniformMatrix4fv_client_proc_t m_glUniformMatrix4fv_enc;
+
+    static void s_glUseProgram(void *self, GLuint program);
+	static void s_glUniform1f(void *self , GLint location, GLfloat x);
+	static void s_glUniform1fv(void *self , GLint location, GLsizei count, const GLfloat* v);
+	static void s_glUniform1i(void *self , GLint location, GLint x);
+	static void s_glUniform1iv(void *self , GLint location, GLsizei count, const GLint* v);
+	static void s_glUniform2f(void *self , GLint location, GLfloat x, GLfloat y);
+	static void s_glUniform2fv(void *self , GLint location, GLsizei count, const GLfloat* v);
+	static void s_glUniform2i(void *self , GLint location, GLint x, GLint y);
+	static void s_glUniform2iv(void *self , GLint location, GLsizei count, const GLint* v);
+	static void s_glUniform3f(void *self , GLint location, GLfloat x, GLfloat y, GLfloat z);
+	static void s_glUniform3fv(void *self , GLint location, GLsizei count, const GLfloat* v);
+	static void s_glUniform3i(void *self , GLint location, GLint x, GLint y, GLint z);
+	static void s_glUniform3iv(void *self , GLint location, GLsizei count, const GLint* v);
+	static void s_glUniform4f(void *self , GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+	static void s_glUniform4fv(void *self , GLint location, GLsizei count, const GLfloat* v);
+	static void s_glUniform4i(void *self , GLint location, GLint x, GLint y, GLint z, GLint w);
+	static void s_glUniform4iv(void *self , GLint location, GLsizei count, const GLint* v);
+	static void s_glUniformMatrix2fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+	static void s_glUniformMatrix3fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+	static void s_glUniformMatrix4fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+
+    glActiveTexture_client_proc_t m_glActiveTexture_enc;
+    glBindTexture_client_proc_t m_glBindTexture_enc;
+    glDeleteTextures_client_proc_t m_glDeleteTextures_enc;
+    glGetTexParameterfv_client_proc_t m_glGetTexParameterfv_enc;
+    glGetTexParameteriv_client_proc_t m_glGetTexParameteriv_enc;
+    glTexParameterf_client_proc_t m_glTexParameterf_enc;
+    glTexParameterfv_client_proc_t m_glTexParameterfv_enc;
+    glTexParameteri_client_proc_t m_glTexParameteri_enc;
+    glTexParameteriv_client_proc_t m_glTexParameteriv_enc;
+
+    static void s_glActiveTexture(void* self, GLenum texture);
+    static void s_glBindTexture(void* self, GLenum target, GLuint texture);
+    static void s_glDeleteTextures(void* self, GLsizei n, const GLuint* textures);
+    static void s_glGetTexParameterfv(void* self, GLenum target, GLenum pname, GLfloat* params);
+    static void s_glGetTexParameteriv(void* self, GLenum target, GLenum pname, GLint* params);
+    static void s_glTexParameterf(void* self, GLenum target, GLenum pname, GLfloat param);
+    static void s_glTexParameterfv(void* self, GLenum target, GLenum pname, const GLfloat* params);
+    static void s_glTexParameteri(void* self, GLenum target, GLenum pname, GLint param);
+    static void s_glTexParameteriv(void* self, GLenum target, GLenum pname, const GLint* params);
+};
+#endif
diff --git a/opengl/system/GLESv2_enc/GL2EncoderUtils.cpp b/opengl/system/GLESv2_enc/GL2EncoderUtils.cpp
new file mode 100644
index 0000000..57d65c0
--- /dev/null
+++ b/opengl/system/GLESv2_enc/GL2EncoderUtils.cpp
@@ -0,0 +1,39 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include "GL2Encoder.h"
+#include <assert.h>
+
+size_t pixelDataSize(void *self, GLsizei width, GLsizei height, GLenum format, GLenum type, int pack)
+{
+    GL2Encoder *ctx = (GL2Encoder *)self;
+    assert (ctx->state() != NULL);
+    return ctx->state()->pixelDataSize(width, height, format, type, pack);
+}
+
+size_t pixelDataSize3D(void *self, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, int pack)
+{
+    size_t layerSize = pixelDataSize(self, width, height, format, type, pack);
+    return layerSize * depth;
+}
+
+GLenum uniformType(void * self, GLuint program, GLint location)
+{
+    GL2Encoder * ctx = (GL2Encoder *) self;
+    assert (ctx->shared() != NULL);
+    return ctx->shared()->getProgramUniformType(program, location);
+}
diff --git a/opengl/system/GLESv2_enc/GL2EncoderUtils.h b/opengl/system/GLESv2_enc/GL2EncoderUtils.h
new file mode 100644
index 0000000..8e91aeb
--- /dev/null
+++ b/opengl/system/GLESv2_enc/GL2EncoderUtils.h
@@ -0,0 +1,24 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#ifndef GL2_ENCODER_UTILS_H
+#define GL2_ENCLODER_UTILS_H
+
+extern "C" {
+    size_t pixelDataSize(void *self, GLsizei width, GLsizei height, GLenum format, GLenum type, int pack);
+    size_t pixelDataSize3D(void *self, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, int pack);
+    GLenum uniformType(void * self, GLuint program, GLint location);
+};
+#endif
diff --git a/opengl/system/GLESv2_enc/gl2_client_context.cpp b/opengl/system/GLESv2_enc/gl2_client_context.cpp
new file mode 100644
index 0000000..e4e08b2
--- /dev/null
+++ b/opengl/system/GLESv2_enc/gl2_client_context.cpp
@@ -0,0 +1,225 @@
+// Generated Code - DO NOT EDIT !!
+// generated by 'emugen'
+
+
+#include <string.h>
+#include "gl2_client_context.h"
+
+
+#include <stdio.h>
+
+int gl2_client_context_t::initDispatchByName(void *(*getProc)(const char *, void *userData), void *userData)
+{
+	void *ptr;
+
+	ptr = getProc("glActiveTexture", userData); set_glActiveTexture((glActiveTexture_client_proc_t)ptr);
+	ptr = getProc("glAttachShader", userData); set_glAttachShader((glAttachShader_client_proc_t)ptr);
+	ptr = getProc("glBindAttribLocation", userData); set_glBindAttribLocation((glBindAttribLocation_client_proc_t)ptr);
+	ptr = getProc("glBindBuffer", userData); set_glBindBuffer((glBindBuffer_client_proc_t)ptr);
+	ptr = getProc("glBindFramebuffer", userData); set_glBindFramebuffer((glBindFramebuffer_client_proc_t)ptr);
+	ptr = getProc("glBindRenderbuffer", userData); set_glBindRenderbuffer((glBindRenderbuffer_client_proc_t)ptr);
+	ptr = getProc("glBindTexture", userData); set_glBindTexture((glBindTexture_client_proc_t)ptr);
+	ptr = getProc("glBlendColor", userData); set_glBlendColor((glBlendColor_client_proc_t)ptr);
+	ptr = getProc("glBlendEquation", userData); set_glBlendEquation((glBlendEquation_client_proc_t)ptr);
+	ptr = getProc("glBlendEquationSeparate", userData); set_glBlendEquationSeparate((glBlendEquationSeparate_client_proc_t)ptr);
+	ptr = getProc("glBlendFunc", userData); set_glBlendFunc((glBlendFunc_client_proc_t)ptr);
+	ptr = getProc("glBlendFuncSeparate", userData); set_glBlendFuncSeparate((glBlendFuncSeparate_client_proc_t)ptr);
+	ptr = getProc("glBufferData", userData); set_glBufferData((glBufferData_client_proc_t)ptr);
+	ptr = getProc("glBufferSubData", userData); set_glBufferSubData((glBufferSubData_client_proc_t)ptr);
+	ptr = getProc("glCheckFramebufferStatus", userData); set_glCheckFramebufferStatus((glCheckFramebufferStatus_client_proc_t)ptr);
+	ptr = getProc("glClear", userData); set_glClear((glClear_client_proc_t)ptr);
+	ptr = getProc("glClearColor", userData); set_glClearColor((glClearColor_client_proc_t)ptr);
+	ptr = getProc("glClearDepthf", userData); set_glClearDepthf((glClearDepthf_client_proc_t)ptr);
+	ptr = getProc("glClearStencil", userData); set_glClearStencil((glClearStencil_client_proc_t)ptr);
+	ptr = getProc("glColorMask", userData); set_glColorMask((glColorMask_client_proc_t)ptr);
+	ptr = getProc("glCompileShader", userData); set_glCompileShader((glCompileShader_client_proc_t)ptr);
+	ptr = getProc("glCompressedTexImage2D", userData); set_glCompressedTexImage2D((glCompressedTexImage2D_client_proc_t)ptr);
+	ptr = getProc("glCompressedTexSubImage2D", userData); set_glCompressedTexSubImage2D((glCompressedTexSubImage2D_client_proc_t)ptr);
+	ptr = getProc("glCopyTexImage2D", userData); set_glCopyTexImage2D((glCopyTexImage2D_client_proc_t)ptr);
+	ptr = getProc("glCopyTexSubImage2D", userData); set_glCopyTexSubImage2D((glCopyTexSubImage2D_client_proc_t)ptr);
+	ptr = getProc("glCreateProgram", userData); set_glCreateProgram((glCreateProgram_client_proc_t)ptr);
+	ptr = getProc("glCreateShader", userData); set_glCreateShader((glCreateShader_client_proc_t)ptr);
+	ptr = getProc("glCullFace", userData); set_glCullFace((glCullFace_client_proc_t)ptr);
+	ptr = getProc("glDeleteBuffers", userData); set_glDeleteBuffers((glDeleteBuffers_client_proc_t)ptr);
+	ptr = getProc("glDeleteFramebuffers", userData); set_glDeleteFramebuffers((glDeleteFramebuffers_client_proc_t)ptr);
+	ptr = getProc("glDeleteProgram", userData); set_glDeleteProgram((glDeleteProgram_client_proc_t)ptr);
+	ptr = getProc("glDeleteRenderbuffers", userData); set_glDeleteRenderbuffers((glDeleteRenderbuffers_client_proc_t)ptr);
+	ptr = getProc("glDeleteShader", userData); set_glDeleteShader((glDeleteShader_client_proc_t)ptr);
+	ptr = getProc("glDeleteTextures", userData); set_glDeleteTextures((glDeleteTextures_client_proc_t)ptr);
+	ptr = getProc("glDepthFunc", userData); set_glDepthFunc((glDepthFunc_client_proc_t)ptr);
+	ptr = getProc("glDepthMask", userData); set_glDepthMask((glDepthMask_client_proc_t)ptr);
+	ptr = getProc("glDepthRangef", userData); set_glDepthRangef((glDepthRangef_client_proc_t)ptr);
+	ptr = getProc("glDetachShader", userData); set_glDetachShader((glDetachShader_client_proc_t)ptr);
+	ptr = getProc("glDisable", userData); set_glDisable((glDisable_client_proc_t)ptr);
+	ptr = getProc("glDisableVertexAttribArray", userData); set_glDisableVertexAttribArray((glDisableVertexAttribArray_client_proc_t)ptr);
+	ptr = getProc("glDrawArrays", userData); set_glDrawArrays((glDrawArrays_client_proc_t)ptr);
+	ptr = getProc("glDrawElements", userData); set_glDrawElements((glDrawElements_client_proc_t)ptr);
+	ptr = getProc("glEnable", userData); set_glEnable((glEnable_client_proc_t)ptr);
+	ptr = getProc("glEnableVertexAttribArray", userData); set_glEnableVertexAttribArray((glEnableVertexAttribArray_client_proc_t)ptr);
+	ptr = getProc("glFinish", userData); set_glFinish((glFinish_client_proc_t)ptr);
+	ptr = getProc("glFlush", userData); set_glFlush((glFlush_client_proc_t)ptr);
+	ptr = getProc("glFramebufferRenderbuffer", userData); set_glFramebufferRenderbuffer((glFramebufferRenderbuffer_client_proc_t)ptr);
+	ptr = getProc("glFramebufferTexture2D", userData); set_glFramebufferTexture2D((glFramebufferTexture2D_client_proc_t)ptr);
+	ptr = getProc("glFrontFace", userData); set_glFrontFace((glFrontFace_client_proc_t)ptr);
+	ptr = getProc("glGenBuffers", userData); set_glGenBuffers((glGenBuffers_client_proc_t)ptr);
+	ptr = getProc("glGenerateMipmap", userData); set_glGenerateMipmap((glGenerateMipmap_client_proc_t)ptr);
+	ptr = getProc("glGenFramebuffers", userData); set_glGenFramebuffers((glGenFramebuffers_client_proc_t)ptr);
+	ptr = getProc("glGenRenderbuffers", userData); set_glGenRenderbuffers((glGenRenderbuffers_client_proc_t)ptr);
+	ptr = getProc("glGenTextures", userData); set_glGenTextures((glGenTextures_client_proc_t)ptr);
+	ptr = getProc("glGetActiveAttrib", userData); set_glGetActiveAttrib((glGetActiveAttrib_client_proc_t)ptr);
+	ptr = getProc("glGetActiveUniform", userData); set_glGetActiveUniform((glGetActiveUniform_client_proc_t)ptr);
+	ptr = getProc("glGetAttachedShaders", userData); set_glGetAttachedShaders((glGetAttachedShaders_client_proc_t)ptr);
+	ptr = getProc("glGetAttribLocation", userData); set_glGetAttribLocation((glGetAttribLocation_client_proc_t)ptr);
+	ptr = getProc("glGetBooleanv", userData); set_glGetBooleanv((glGetBooleanv_client_proc_t)ptr);
+	ptr = getProc("glGetBufferParameteriv", userData); set_glGetBufferParameteriv((glGetBufferParameteriv_client_proc_t)ptr);
+	ptr = getProc("glGetError", userData); set_glGetError((glGetError_client_proc_t)ptr);
+	ptr = getProc("glGetFloatv", userData); set_glGetFloatv((glGetFloatv_client_proc_t)ptr);
+	ptr = getProc("glGetFramebufferAttachmentParameteriv", userData); set_glGetFramebufferAttachmentParameteriv((glGetFramebufferAttachmentParameteriv_client_proc_t)ptr);
+	ptr = getProc("glGetIntegerv", userData); set_glGetIntegerv((glGetIntegerv_client_proc_t)ptr);
+	ptr = getProc("glGetProgramiv", userData); set_glGetProgramiv((glGetProgramiv_client_proc_t)ptr);
+	ptr = getProc("glGetProgramInfoLog", userData); set_glGetProgramInfoLog((glGetProgramInfoLog_client_proc_t)ptr);
+	ptr = getProc("glGetRenderbufferParameteriv", userData); set_glGetRenderbufferParameteriv((glGetRenderbufferParameteriv_client_proc_t)ptr);
+	ptr = getProc("glGetShaderiv", userData); set_glGetShaderiv((glGetShaderiv_client_proc_t)ptr);
+	ptr = getProc("glGetShaderInfoLog", userData); set_glGetShaderInfoLog((glGetShaderInfoLog_client_proc_t)ptr);
+	ptr = getProc("glGetShaderPrecisionFormat", userData); set_glGetShaderPrecisionFormat((glGetShaderPrecisionFormat_client_proc_t)ptr);
+	ptr = getProc("glGetShaderSource", userData); set_glGetShaderSource((glGetShaderSource_client_proc_t)ptr);
+	ptr = getProc("glGetString", userData); set_glGetString((glGetString_client_proc_t)ptr);
+	ptr = getProc("glGetTexParameterfv", userData); set_glGetTexParameterfv((glGetTexParameterfv_client_proc_t)ptr);
+	ptr = getProc("glGetTexParameteriv", userData); set_glGetTexParameteriv((glGetTexParameteriv_client_proc_t)ptr);
+	ptr = getProc("glGetUniformfv", userData); set_glGetUniformfv((glGetUniformfv_client_proc_t)ptr);
+	ptr = getProc("glGetUniformiv", userData); set_glGetUniformiv((glGetUniformiv_client_proc_t)ptr);
+	ptr = getProc("glGetUniformLocation", userData); set_glGetUniformLocation((glGetUniformLocation_client_proc_t)ptr);
+	ptr = getProc("glGetVertexAttribfv", userData); set_glGetVertexAttribfv((glGetVertexAttribfv_client_proc_t)ptr);
+	ptr = getProc("glGetVertexAttribiv", userData); set_glGetVertexAttribiv((glGetVertexAttribiv_client_proc_t)ptr);
+	ptr = getProc("glGetVertexAttribPointerv", userData); set_glGetVertexAttribPointerv((glGetVertexAttribPointerv_client_proc_t)ptr);
+	ptr = getProc("glHint", userData); set_glHint((glHint_client_proc_t)ptr);
+	ptr = getProc("glIsBuffer", userData); set_glIsBuffer((glIsBuffer_client_proc_t)ptr);
+	ptr = getProc("glIsEnabled", userData); set_glIsEnabled((glIsEnabled_client_proc_t)ptr);
+	ptr = getProc("glIsFramebuffer", userData); set_glIsFramebuffer((glIsFramebuffer_client_proc_t)ptr);
+	ptr = getProc("glIsProgram", userData); set_glIsProgram((glIsProgram_client_proc_t)ptr);
+	ptr = getProc("glIsRenderbuffer", userData); set_glIsRenderbuffer((glIsRenderbuffer_client_proc_t)ptr);
+	ptr = getProc("glIsShader", userData); set_glIsShader((glIsShader_client_proc_t)ptr);
+	ptr = getProc("glIsTexture", userData); set_glIsTexture((glIsTexture_client_proc_t)ptr);
+	ptr = getProc("glLineWidth", userData); set_glLineWidth((glLineWidth_client_proc_t)ptr);
+	ptr = getProc("glLinkProgram", userData); set_glLinkProgram((glLinkProgram_client_proc_t)ptr);
+	ptr = getProc("glPixelStorei", userData); set_glPixelStorei((glPixelStorei_client_proc_t)ptr);
+	ptr = getProc("glPolygonOffset", userData); set_glPolygonOffset((glPolygonOffset_client_proc_t)ptr);
+	ptr = getProc("glReadPixels", userData); set_glReadPixels((glReadPixels_client_proc_t)ptr);
+	ptr = getProc("glReleaseShaderCompiler", userData); set_glReleaseShaderCompiler((glReleaseShaderCompiler_client_proc_t)ptr);
+	ptr = getProc("glRenderbufferStorage", userData); set_glRenderbufferStorage((glRenderbufferStorage_client_proc_t)ptr);
+	ptr = getProc("glSampleCoverage", userData); set_glSampleCoverage((glSampleCoverage_client_proc_t)ptr);
+	ptr = getProc("glScissor", userData); set_glScissor((glScissor_client_proc_t)ptr);
+	ptr = getProc("glShaderBinary", userData); set_glShaderBinary((glShaderBinary_client_proc_t)ptr);
+	ptr = getProc("glShaderSource", userData); set_glShaderSource((glShaderSource_client_proc_t)ptr);
+	ptr = getProc("glStencilFunc", userData); set_glStencilFunc((glStencilFunc_client_proc_t)ptr);
+	ptr = getProc("glStencilFuncSeparate", userData); set_glStencilFuncSeparate((glStencilFuncSeparate_client_proc_t)ptr);
+	ptr = getProc("glStencilMask", userData); set_glStencilMask((glStencilMask_client_proc_t)ptr);
+	ptr = getProc("glStencilMaskSeparate", userData); set_glStencilMaskSeparate((glStencilMaskSeparate_client_proc_t)ptr);
+	ptr = getProc("glStencilOp", userData); set_glStencilOp((glStencilOp_client_proc_t)ptr);
+	ptr = getProc("glStencilOpSeparate", userData); set_glStencilOpSeparate((glStencilOpSeparate_client_proc_t)ptr);
+	ptr = getProc("glTexImage2D", userData); set_glTexImage2D((glTexImage2D_client_proc_t)ptr);
+	ptr = getProc("glTexParameterf", userData); set_glTexParameterf((glTexParameterf_client_proc_t)ptr);
+	ptr = getProc("glTexParameterfv", userData); set_glTexParameterfv((glTexParameterfv_client_proc_t)ptr);
+	ptr = getProc("glTexParameteri", userData); set_glTexParameteri((glTexParameteri_client_proc_t)ptr);
+	ptr = getProc("glTexParameteriv", userData); set_glTexParameteriv((glTexParameteriv_client_proc_t)ptr);
+	ptr = getProc("glTexSubImage2D", userData); set_glTexSubImage2D((glTexSubImage2D_client_proc_t)ptr);
+	ptr = getProc("glUniform1f", userData); set_glUniform1f((glUniform1f_client_proc_t)ptr);
+	ptr = getProc("glUniform1fv", userData); set_glUniform1fv((glUniform1fv_client_proc_t)ptr);
+	ptr = getProc("glUniform1i", userData); set_glUniform1i((glUniform1i_client_proc_t)ptr);
+	ptr = getProc("glUniform1iv", userData); set_glUniform1iv((glUniform1iv_client_proc_t)ptr);
+	ptr = getProc("glUniform2f", userData); set_glUniform2f((glUniform2f_client_proc_t)ptr);
+	ptr = getProc("glUniform2fv", userData); set_glUniform2fv((glUniform2fv_client_proc_t)ptr);
+	ptr = getProc("glUniform2i", userData); set_glUniform2i((glUniform2i_client_proc_t)ptr);
+	ptr = getProc("glUniform2iv", userData); set_glUniform2iv((glUniform2iv_client_proc_t)ptr);
+	ptr = getProc("glUniform3f", userData); set_glUniform3f((glUniform3f_client_proc_t)ptr);
+	ptr = getProc("glUniform3fv", userData); set_glUniform3fv((glUniform3fv_client_proc_t)ptr);
+	ptr = getProc("glUniform3i", userData); set_glUniform3i((glUniform3i_client_proc_t)ptr);
+	ptr = getProc("glUniform3iv", userData); set_glUniform3iv((glUniform3iv_client_proc_t)ptr);
+	ptr = getProc("glUniform4f", userData); set_glUniform4f((glUniform4f_client_proc_t)ptr);
+	ptr = getProc("glUniform4fv", userData); set_glUniform4fv((glUniform4fv_client_proc_t)ptr);
+	ptr = getProc("glUniform4i", userData); set_glUniform4i((glUniform4i_client_proc_t)ptr);
+	ptr = getProc("glUniform4iv", userData); set_glUniform4iv((glUniform4iv_client_proc_t)ptr);
+	ptr = getProc("glUniformMatrix2fv", userData); set_glUniformMatrix2fv((glUniformMatrix2fv_client_proc_t)ptr);
+	ptr = getProc("glUniformMatrix3fv", userData); set_glUniformMatrix3fv((glUniformMatrix3fv_client_proc_t)ptr);
+	ptr = getProc("glUniformMatrix4fv", userData); set_glUniformMatrix4fv((glUniformMatrix4fv_client_proc_t)ptr);
+	ptr = getProc("glUseProgram", userData); set_glUseProgram((glUseProgram_client_proc_t)ptr);
+	ptr = getProc("glValidateProgram", userData); set_glValidateProgram((glValidateProgram_client_proc_t)ptr);
+	ptr = getProc("glVertexAttrib1f", userData); set_glVertexAttrib1f((glVertexAttrib1f_client_proc_t)ptr);
+	ptr = getProc("glVertexAttrib1fv", userData); set_glVertexAttrib1fv((glVertexAttrib1fv_client_proc_t)ptr);
+	ptr = getProc("glVertexAttrib2f", userData); set_glVertexAttrib2f((glVertexAttrib2f_client_proc_t)ptr);
+	ptr = getProc("glVertexAttrib2fv", userData); set_glVertexAttrib2fv((glVertexAttrib2fv_client_proc_t)ptr);
+	ptr = getProc("glVertexAttrib3f", userData); set_glVertexAttrib3f((glVertexAttrib3f_client_proc_t)ptr);
+	ptr = getProc("glVertexAttrib3fv", userData); set_glVertexAttrib3fv((glVertexAttrib3fv_client_proc_t)ptr);
+	ptr = getProc("glVertexAttrib4f", userData); set_glVertexAttrib4f((glVertexAttrib4f_client_proc_t)ptr);
+	ptr = getProc("glVertexAttrib4fv", userData); set_glVertexAttrib4fv((glVertexAttrib4fv_client_proc_t)ptr);
+	ptr = getProc("glVertexAttribPointer", userData); set_glVertexAttribPointer((glVertexAttribPointer_client_proc_t)ptr);
+	ptr = getProc("glViewport", userData); set_glViewport((glViewport_client_proc_t)ptr);
+	ptr = getProc("glEGLImageTargetTexture2DOES", userData); set_glEGLImageTargetTexture2DOES((glEGLImageTargetTexture2DOES_client_proc_t)ptr);
+	ptr = getProc("glEGLImageTargetRenderbufferStorageOES", userData); set_glEGLImageTargetRenderbufferStorageOES((glEGLImageTargetRenderbufferStorageOES_client_proc_t)ptr);
+	ptr = getProc("glGetProgramBinaryOES", userData); set_glGetProgramBinaryOES((glGetProgramBinaryOES_client_proc_t)ptr);
+	ptr = getProc("glProgramBinaryOES", userData); set_glProgramBinaryOES((glProgramBinaryOES_client_proc_t)ptr);
+	ptr = getProc("glMapBufferOES", userData); set_glMapBufferOES((glMapBufferOES_client_proc_t)ptr);
+	ptr = getProc("glUnmapBufferOES", userData); set_glUnmapBufferOES((glUnmapBufferOES_client_proc_t)ptr);
+	ptr = getProc("glTexImage3DOES", userData); set_glTexImage3DOES((glTexImage3DOES_client_proc_t)ptr);
+	ptr = getProc("glTexSubImage3DOES", userData); set_glTexSubImage3DOES((glTexSubImage3DOES_client_proc_t)ptr);
+	ptr = getProc("glCopyTexSubImage3DOES", userData); set_glCopyTexSubImage3DOES((glCopyTexSubImage3DOES_client_proc_t)ptr);
+	ptr = getProc("glCompressedTexImage3DOES", userData); set_glCompressedTexImage3DOES((glCompressedTexImage3DOES_client_proc_t)ptr);
+	ptr = getProc("glCompressedTexSubImage3DOES", userData); set_glCompressedTexSubImage3DOES((glCompressedTexSubImage3DOES_client_proc_t)ptr);
+	ptr = getProc("glFramebufferTexture3DOES", userData); set_glFramebufferTexture3DOES((glFramebufferTexture3DOES_client_proc_t)ptr);
+	ptr = getProc("glBindVertexArrayOES", userData); set_glBindVertexArrayOES((glBindVertexArrayOES_client_proc_t)ptr);
+	ptr = getProc("glDeleteVertexArraysOES", userData); set_glDeleteVertexArraysOES((glDeleteVertexArraysOES_client_proc_t)ptr);
+	ptr = getProc("glGenVertexArraysOES", userData); set_glGenVertexArraysOES((glGenVertexArraysOES_client_proc_t)ptr);
+	ptr = getProc("glIsVertexArrayOES", userData); set_glIsVertexArrayOES((glIsVertexArrayOES_client_proc_t)ptr);
+	ptr = getProc("glDiscardFramebufferEXT", userData); set_glDiscardFramebufferEXT((glDiscardFramebufferEXT_client_proc_t)ptr);
+	ptr = getProc("glMultiDrawArraysEXT", userData); set_glMultiDrawArraysEXT((glMultiDrawArraysEXT_client_proc_t)ptr);
+	ptr = getProc("glMultiDrawElementsEXT", userData); set_glMultiDrawElementsEXT((glMultiDrawElementsEXT_client_proc_t)ptr);
+	ptr = getProc("glGetPerfMonitorGroupsAMD", userData); set_glGetPerfMonitorGroupsAMD((glGetPerfMonitorGroupsAMD_client_proc_t)ptr);
+	ptr = getProc("glGetPerfMonitorCountersAMD", userData); set_glGetPerfMonitorCountersAMD((glGetPerfMonitorCountersAMD_client_proc_t)ptr);
+	ptr = getProc("glGetPerfMonitorGroupStringAMD", userData); set_glGetPerfMonitorGroupStringAMD((glGetPerfMonitorGroupStringAMD_client_proc_t)ptr);
+	ptr = getProc("glGetPerfMonitorCounterStringAMD", userData); set_glGetPerfMonitorCounterStringAMD((glGetPerfMonitorCounterStringAMD_client_proc_t)ptr);
+	ptr = getProc("glGetPerfMonitorCounterInfoAMD", userData); set_glGetPerfMonitorCounterInfoAMD((glGetPerfMonitorCounterInfoAMD_client_proc_t)ptr);
+	ptr = getProc("glGenPerfMonitorsAMD", userData); set_glGenPerfMonitorsAMD((glGenPerfMonitorsAMD_client_proc_t)ptr);
+	ptr = getProc("glDeletePerfMonitorsAMD", userData); set_glDeletePerfMonitorsAMD((glDeletePerfMonitorsAMD_client_proc_t)ptr);
+	ptr = getProc("glSelectPerfMonitorCountersAMD", userData); set_glSelectPerfMonitorCountersAMD((glSelectPerfMonitorCountersAMD_client_proc_t)ptr);
+	ptr = getProc("glBeginPerfMonitorAMD", userData); set_glBeginPerfMonitorAMD((glBeginPerfMonitorAMD_client_proc_t)ptr);
+	ptr = getProc("glEndPerfMonitorAMD", userData); set_glEndPerfMonitorAMD((glEndPerfMonitorAMD_client_proc_t)ptr);
+	ptr = getProc("glGetPerfMonitorCounterDataAMD", userData); set_glGetPerfMonitorCounterDataAMD((glGetPerfMonitorCounterDataAMD_client_proc_t)ptr);
+	ptr = getProc("glRenderbufferStorageMultisampleIMG", userData); set_glRenderbufferStorageMultisampleIMG((glRenderbufferStorageMultisampleIMG_client_proc_t)ptr);
+	ptr = getProc("glFramebufferTexture2DMultisampleIMG", userData); set_glFramebufferTexture2DMultisampleIMG((glFramebufferTexture2DMultisampleIMG_client_proc_t)ptr);
+	ptr = getProc("glDeleteFencesNV", userData); set_glDeleteFencesNV((glDeleteFencesNV_client_proc_t)ptr);
+	ptr = getProc("glGenFencesNV", userData); set_glGenFencesNV((glGenFencesNV_client_proc_t)ptr);
+	ptr = getProc("glIsFenceNV", userData); set_glIsFenceNV((glIsFenceNV_client_proc_t)ptr);
+	ptr = getProc("glTestFenceNV", userData); set_glTestFenceNV((glTestFenceNV_client_proc_t)ptr);
+	ptr = getProc("glGetFenceivNV", userData); set_glGetFenceivNV((glGetFenceivNV_client_proc_t)ptr);
+	ptr = getProc("glFinishFenceNV", userData); set_glFinishFenceNV((glFinishFenceNV_client_proc_t)ptr);
+	ptr = getProc("glSetFenceNV", userData); set_glSetFenceNV((glSetFenceNV_client_proc_t)ptr);
+	ptr = getProc("glCoverageMaskNV", userData); set_glCoverageMaskNV((glCoverageMaskNV_client_proc_t)ptr);
+	ptr = getProc("glCoverageOperationNV", userData); set_glCoverageOperationNV((glCoverageOperationNV_client_proc_t)ptr);
+	ptr = getProc("glGetDriverControlsQCOM", userData); set_glGetDriverControlsQCOM((glGetDriverControlsQCOM_client_proc_t)ptr);
+	ptr = getProc("glGetDriverControlStringQCOM", userData); set_glGetDriverControlStringQCOM((glGetDriverControlStringQCOM_client_proc_t)ptr);
+	ptr = getProc("glEnableDriverControlQCOM", userData); set_glEnableDriverControlQCOM((glEnableDriverControlQCOM_client_proc_t)ptr);
+	ptr = getProc("glDisableDriverControlQCOM", userData); set_glDisableDriverControlQCOM((glDisableDriverControlQCOM_client_proc_t)ptr);
+	ptr = getProc("glExtGetTexturesQCOM", userData); set_glExtGetTexturesQCOM((glExtGetTexturesQCOM_client_proc_t)ptr);
+	ptr = getProc("glExtGetBuffersQCOM", userData); set_glExtGetBuffersQCOM((glExtGetBuffersQCOM_client_proc_t)ptr);
+	ptr = getProc("glExtGetRenderbuffersQCOM", userData); set_glExtGetRenderbuffersQCOM((glExtGetRenderbuffersQCOM_client_proc_t)ptr);
+	ptr = getProc("glExtGetFramebuffersQCOM", userData); set_glExtGetFramebuffersQCOM((glExtGetFramebuffersQCOM_client_proc_t)ptr);
+	ptr = getProc("glExtGetTexLevelParameterivQCOM", userData); set_glExtGetTexLevelParameterivQCOM((glExtGetTexLevelParameterivQCOM_client_proc_t)ptr);
+	ptr = getProc("glExtTexObjectStateOverrideiQCOM", userData); set_glExtTexObjectStateOverrideiQCOM((glExtTexObjectStateOverrideiQCOM_client_proc_t)ptr);
+	ptr = getProc("glExtGetTexSubImageQCOM", userData); set_glExtGetTexSubImageQCOM((glExtGetTexSubImageQCOM_client_proc_t)ptr);
+	ptr = getProc("glExtGetBufferPointervQCOM", userData); set_glExtGetBufferPointervQCOM((glExtGetBufferPointervQCOM_client_proc_t)ptr);
+	ptr = getProc("glExtGetShadersQCOM", userData); set_glExtGetShadersQCOM((glExtGetShadersQCOM_client_proc_t)ptr);
+	ptr = getProc("glExtGetProgramsQCOM", userData); set_glExtGetProgramsQCOM((glExtGetProgramsQCOM_client_proc_t)ptr);
+	ptr = getProc("glExtIsProgramBinaryQCOM", userData); set_glExtIsProgramBinaryQCOM((glExtIsProgramBinaryQCOM_client_proc_t)ptr);
+	ptr = getProc("glExtGetProgramBinarySourceQCOM", userData); set_glExtGetProgramBinarySourceQCOM((glExtGetProgramBinarySourceQCOM_client_proc_t)ptr);
+	ptr = getProc("glStartTilingQCOM", userData); set_glStartTilingQCOM((glStartTilingQCOM_client_proc_t)ptr);
+	ptr = getProc("glEndTilingQCOM", userData); set_glEndTilingQCOM((glEndTilingQCOM_client_proc_t)ptr);
+	ptr = getProc("glVertexAttribPointerData", userData); set_glVertexAttribPointerData((glVertexAttribPointerData_client_proc_t)ptr);
+	ptr = getProc("glVertexAttribPointerOffset", userData); set_glVertexAttribPointerOffset((glVertexAttribPointerOffset_client_proc_t)ptr);
+	ptr = getProc("glDrawElementsOffset", userData); set_glDrawElementsOffset((glDrawElementsOffset_client_proc_t)ptr);
+	ptr = getProc("glDrawElementsData", userData); set_glDrawElementsData((glDrawElementsData_client_proc_t)ptr);
+	ptr = getProc("glGetCompressedTextureFormats", userData); set_glGetCompressedTextureFormats((glGetCompressedTextureFormats_client_proc_t)ptr);
+	ptr = getProc("glShaderString", userData); set_glShaderString((glShaderString_client_proc_t)ptr);
+	ptr = getProc("glFinishRoundTrip", userData); set_glFinishRoundTrip((glFinishRoundTrip_client_proc_t)ptr);
+	return 0;
+}
+
diff --git a/opengl/system/GLESv2_enc/gl2_client_context.h b/opengl/system/GLESv2_enc/gl2_client_context.h
new file mode 100644
index 0000000..7f0abcd
--- /dev/null
+++ b/opengl/system/GLESv2_enc/gl2_client_context.h
@@ -0,0 +1,437 @@
+// Generated Code - DO NOT EDIT !!
+// generated by 'emugen'
+#ifndef __gl2_client_context_t_h
+#define __gl2_client_context_t_h
+
+#include "gl2_client_proc.h"
+
+
+struct gl2_client_context_t {
+
+	glActiveTexture_client_proc_t glActiveTexture;
+	glAttachShader_client_proc_t glAttachShader;
+	glBindAttribLocation_client_proc_t glBindAttribLocation;
+	glBindBuffer_client_proc_t glBindBuffer;
+	glBindFramebuffer_client_proc_t glBindFramebuffer;
+	glBindRenderbuffer_client_proc_t glBindRenderbuffer;
+	glBindTexture_client_proc_t glBindTexture;
+	glBlendColor_client_proc_t glBlendColor;
+	glBlendEquation_client_proc_t glBlendEquation;
+	glBlendEquationSeparate_client_proc_t glBlendEquationSeparate;
+	glBlendFunc_client_proc_t glBlendFunc;
+	glBlendFuncSeparate_client_proc_t glBlendFuncSeparate;
+	glBufferData_client_proc_t glBufferData;
+	glBufferSubData_client_proc_t glBufferSubData;
+	glCheckFramebufferStatus_client_proc_t glCheckFramebufferStatus;
+	glClear_client_proc_t glClear;
+	glClearColor_client_proc_t glClearColor;
+	glClearDepthf_client_proc_t glClearDepthf;
+	glClearStencil_client_proc_t glClearStencil;
+	glColorMask_client_proc_t glColorMask;
+	glCompileShader_client_proc_t glCompileShader;
+	glCompressedTexImage2D_client_proc_t glCompressedTexImage2D;
+	glCompressedTexSubImage2D_client_proc_t glCompressedTexSubImage2D;
+	glCopyTexImage2D_client_proc_t glCopyTexImage2D;
+	glCopyTexSubImage2D_client_proc_t glCopyTexSubImage2D;
+	glCreateProgram_client_proc_t glCreateProgram;
+	glCreateShader_client_proc_t glCreateShader;
+	glCullFace_client_proc_t glCullFace;
+	glDeleteBuffers_client_proc_t glDeleteBuffers;
+	glDeleteFramebuffers_client_proc_t glDeleteFramebuffers;
+	glDeleteProgram_client_proc_t glDeleteProgram;
+	glDeleteRenderbuffers_client_proc_t glDeleteRenderbuffers;
+	glDeleteShader_client_proc_t glDeleteShader;
+	glDeleteTextures_client_proc_t glDeleteTextures;
+	glDepthFunc_client_proc_t glDepthFunc;
+	glDepthMask_client_proc_t glDepthMask;
+	glDepthRangef_client_proc_t glDepthRangef;
+	glDetachShader_client_proc_t glDetachShader;
+	glDisable_client_proc_t glDisable;
+	glDisableVertexAttribArray_client_proc_t glDisableVertexAttribArray;
+	glDrawArrays_client_proc_t glDrawArrays;
+	glDrawElements_client_proc_t glDrawElements;
+	glEnable_client_proc_t glEnable;
+	glEnableVertexAttribArray_client_proc_t glEnableVertexAttribArray;
+	glFinish_client_proc_t glFinish;
+	glFlush_client_proc_t glFlush;
+	glFramebufferRenderbuffer_client_proc_t glFramebufferRenderbuffer;
+	glFramebufferTexture2D_client_proc_t glFramebufferTexture2D;
+	glFrontFace_client_proc_t glFrontFace;
+	glGenBuffers_client_proc_t glGenBuffers;
+	glGenerateMipmap_client_proc_t glGenerateMipmap;
+	glGenFramebuffers_client_proc_t glGenFramebuffers;
+	glGenRenderbuffers_client_proc_t glGenRenderbuffers;
+	glGenTextures_client_proc_t glGenTextures;
+	glGetActiveAttrib_client_proc_t glGetActiveAttrib;
+	glGetActiveUniform_client_proc_t glGetActiveUniform;
+	glGetAttachedShaders_client_proc_t glGetAttachedShaders;
+	glGetAttribLocation_client_proc_t glGetAttribLocation;
+	glGetBooleanv_client_proc_t glGetBooleanv;
+	glGetBufferParameteriv_client_proc_t glGetBufferParameteriv;
+	glGetError_client_proc_t glGetError;
+	glGetFloatv_client_proc_t glGetFloatv;
+	glGetFramebufferAttachmentParameteriv_client_proc_t glGetFramebufferAttachmentParameteriv;
+	glGetIntegerv_client_proc_t glGetIntegerv;
+	glGetProgramiv_client_proc_t glGetProgramiv;
+	glGetProgramInfoLog_client_proc_t glGetProgramInfoLog;
+	glGetRenderbufferParameteriv_client_proc_t glGetRenderbufferParameteriv;
+	glGetShaderiv_client_proc_t glGetShaderiv;
+	glGetShaderInfoLog_client_proc_t glGetShaderInfoLog;
+	glGetShaderPrecisionFormat_client_proc_t glGetShaderPrecisionFormat;
+	glGetShaderSource_client_proc_t glGetShaderSource;
+	glGetString_client_proc_t glGetString;
+	glGetTexParameterfv_client_proc_t glGetTexParameterfv;
+	glGetTexParameteriv_client_proc_t glGetTexParameteriv;
+	glGetUniformfv_client_proc_t glGetUniformfv;
+	glGetUniformiv_client_proc_t glGetUniformiv;
+	glGetUniformLocation_client_proc_t glGetUniformLocation;
+	glGetVertexAttribfv_client_proc_t glGetVertexAttribfv;
+	glGetVertexAttribiv_client_proc_t glGetVertexAttribiv;
+	glGetVertexAttribPointerv_client_proc_t glGetVertexAttribPointerv;
+	glHint_client_proc_t glHint;
+	glIsBuffer_client_proc_t glIsBuffer;
+	glIsEnabled_client_proc_t glIsEnabled;
+	glIsFramebuffer_client_proc_t glIsFramebuffer;
+	glIsProgram_client_proc_t glIsProgram;
+	glIsRenderbuffer_client_proc_t glIsRenderbuffer;
+	glIsShader_client_proc_t glIsShader;
+	glIsTexture_client_proc_t glIsTexture;
+	glLineWidth_client_proc_t glLineWidth;
+	glLinkProgram_client_proc_t glLinkProgram;
+	glPixelStorei_client_proc_t glPixelStorei;
+	glPolygonOffset_client_proc_t glPolygonOffset;
+	glReadPixels_client_proc_t glReadPixels;
+	glReleaseShaderCompiler_client_proc_t glReleaseShaderCompiler;
+	glRenderbufferStorage_client_proc_t glRenderbufferStorage;
+	glSampleCoverage_client_proc_t glSampleCoverage;
+	glScissor_client_proc_t glScissor;
+	glShaderBinary_client_proc_t glShaderBinary;
+	glShaderSource_client_proc_t glShaderSource;
+	glStencilFunc_client_proc_t glStencilFunc;
+	glStencilFuncSeparate_client_proc_t glStencilFuncSeparate;
+	glStencilMask_client_proc_t glStencilMask;
+	glStencilMaskSeparate_client_proc_t glStencilMaskSeparate;
+	glStencilOp_client_proc_t glStencilOp;
+	glStencilOpSeparate_client_proc_t glStencilOpSeparate;
+	glTexImage2D_client_proc_t glTexImage2D;
+	glTexParameterf_client_proc_t glTexParameterf;
+	glTexParameterfv_client_proc_t glTexParameterfv;
+	glTexParameteri_client_proc_t glTexParameteri;
+	glTexParameteriv_client_proc_t glTexParameteriv;
+	glTexSubImage2D_client_proc_t glTexSubImage2D;
+	glUniform1f_client_proc_t glUniform1f;
+	glUniform1fv_client_proc_t glUniform1fv;
+	glUniform1i_client_proc_t glUniform1i;
+	glUniform1iv_client_proc_t glUniform1iv;
+	glUniform2f_client_proc_t glUniform2f;
+	glUniform2fv_client_proc_t glUniform2fv;
+	glUniform2i_client_proc_t glUniform2i;
+	glUniform2iv_client_proc_t glUniform2iv;
+	glUniform3f_client_proc_t glUniform3f;
+	glUniform3fv_client_proc_t glUniform3fv;
+	glUniform3i_client_proc_t glUniform3i;
+	glUniform3iv_client_proc_t glUniform3iv;
+	glUniform4f_client_proc_t glUniform4f;
+	glUniform4fv_client_proc_t glUniform4fv;
+	glUniform4i_client_proc_t glUniform4i;
+	glUniform4iv_client_proc_t glUniform4iv;
+	glUniformMatrix2fv_client_proc_t glUniformMatrix2fv;
+	glUniformMatrix3fv_client_proc_t glUniformMatrix3fv;
+	glUniformMatrix4fv_client_proc_t glUniformMatrix4fv;
+	glUseProgram_client_proc_t glUseProgram;
+	glValidateProgram_client_proc_t glValidateProgram;
+	glVertexAttrib1f_client_proc_t glVertexAttrib1f;
+	glVertexAttrib1fv_client_proc_t glVertexAttrib1fv;
+	glVertexAttrib2f_client_proc_t glVertexAttrib2f;
+	glVertexAttrib2fv_client_proc_t glVertexAttrib2fv;
+	glVertexAttrib3f_client_proc_t glVertexAttrib3f;
+	glVertexAttrib3fv_client_proc_t glVertexAttrib3fv;
+	glVertexAttrib4f_client_proc_t glVertexAttrib4f;
+	glVertexAttrib4fv_client_proc_t glVertexAttrib4fv;
+	glVertexAttribPointer_client_proc_t glVertexAttribPointer;
+	glViewport_client_proc_t glViewport;
+	glEGLImageTargetTexture2DOES_client_proc_t glEGLImageTargetTexture2DOES;
+	glEGLImageTargetRenderbufferStorageOES_client_proc_t glEGLImageTargetRenderbufferStorageOES;
+	glGetProgramBinaryOES_client_proc_t glGetProgramBinaryOES;
+	glProgramBinaryOES_client_proc_t glProgramBinaryOES;
+	glMapBufferOES_client_proc_t glMapBufferOES;
+	glUnmapBufferOES_client_proc_t glUnmapBufferOES;
+	glTexImage3DOES_client_proc_t glTexImage3DOES;
+	glTexSubImage3DOES_client_proc_t glTexSubImage3DOES;
+	glCopyTexSubImage3DOES_client_proc_t glCopyTexSubImage3DOES;
+	glCompressedTexImage3DOES_client_proc_t glCompressedTexImage3DOES;
+	glCompressedTexSubImage3DOES_client_proc_t glCompressedTexSubImage3DOES;
+	glFramebufferTexture3DOES_client_proc_t glFramebufferTexture3DOES;
+	glBindVertexArrayOES_client_proc_t glBindVertexArrayOES;
+	glDeleteVertexArraysOES_client_proc_t glDeleteVertexArraysOES;
+	glGenVertexArraysOES_client_proc_t glGenVertexArraysOES;
+	glIsVertexArrayOES_client_proc_t glIsVertexArrayOES;
+	glDiscardFramebufferEXT_client_proc_t glDiscardFramebufferEXT;
+	glMultiDrawArraysEXT_client_proc_t glMultiDrawArraysEXT;
+	glMultiDrawElementsEXT_client_proc_t glMultiDrawElementsEXT;
+	glGetPerfMonitorGroupsAMD_client_proc_t glGetPerfMonitorGroupsAMD;
+	glGetPerfMonitorCountersAMD_client_proc_t glGetPerfMonitorCountersAMD;
+	glGetPerfMonitorGroupStringAMD_client_proc_t glGetPerfMonitorGroupStringAMD;
+	glGetPerfMonitorCounterStringAMD_client_proc_t glGetPerfMonitorCounterStringAMD;
+	glGetPerfMonitorCounterInfoAMD_client_proc_t glGetPerfMonitorCounterInfoAMD;
+	glGenPerfMonitorsAMD_client_proc_t glGenPerfMonitorsAMD;
+	glDeletePerfMonitorsAMD_client_proc_t glDeletePerfMonitorsAMD;
+	glSelectPerfMonitorCountersAMD_client_proc_t glSelectPerfMonitorCountersAMD;
+	glBeginPerfMonitorAMD_client_proc_t glBeginPerfMonitorAMD;
+	glEndPerfMonitorAMD_client_proc_t glEndPerfMonitorAMD;
+	glGetPerfMonitorCounterDataAMD_client_proc_t glGetPerfMonitorCounterDataAMD;
+	glRenderbufferStorageMultisampleIMG_client_proc_t glRenderbufferStorageMultisampleIMG;
+	glFramebufferTexture2DMultisampleIMG_client_proc_t glFramebufferTexture2DMultisampleIMG;
+	glDeleteFencesNV_client_proc_t glDeleteFencesNV;
+	glGenFencesNV_client_proc_t glGenFencesNV;
+	glIsFenceNV_client_proc_t glIsFenceNV;
+	glTestFenceNV_client_proc_t glTestFenceNV;
+	glGetFenceivNV_client_proc_t glGetFenceivNV;
+	glFinishFenceNV_client_proc_t glFinishFenceNV;
+	glSetFenceNV_client_proc_t glSetFenceNV;
+	glCoverageMaskNV_client_proc_t glCoverageMaskNV;
+	glCoverageOperationNV_client_proc_t glCoverageOperationNV;
+	glGetDriverControlsQCOM_client_proc_t glGetDriverControlsQCOM;
+	glGetDriverControlStringQCOM_client_proc_t glGetDriverControlStringQCOM;
+	glEnableDriverControlQCOM_client_proc_t glEnableDriverControlQCOM;
+	glDisableDriverControlQCOM_client_proc_t glDisableDriverControlQCOM;
+	glExtGetTexturesQCOM_client_proc_t glExtGetTexturesQCOM;
+	glExtGetBuffersQCOM_client_proc_t glExtGetBuffersQCOM;
+	glExtGetRenderbuffersQCOM_client_proc_t glExtGetRenderbuffersQCOM;
+	glExtGetFramebuffersQCOM_client_proc_t glExtGetFramebuffersQCOM;
+	glExtGetTexLevelParameterivQCOM_client_proc_t glExtGetTexLevelParameterivQCOM;
+	glExtTexObjectStateOverrideiQCOM_client_proc_t glExtTexObjectStateOverrideiQCOM;
+	glExtGetTexSubImageQCOM_client_proc_t glExtGetTexSubImageQCOM;
+	glExtGetBufferPointervQCOM_client_proc_t glExtGetBufferPointervQCOM;
+	glExtGetShadersQCOM_client_proc_t glExtGetShadersQCOM;
+	glExtGetProgramsQCOM_client_proc_t glExtGetProgramsQCOM;
+	glExtIsProgramBinaryQCOM_client_proc_t glExtIsProgramBinaryQCOM;
+	glExtGetProgramBinarySourceQCOM_client_proc_t glExtGetProgramBinarySourceQCOM;
+	glStartTilingQCOM_client_proc_t glStartTilingQCOM;
+	glEndTilingQCOM_client_proc_t glEndTilingQCOM;
+	glVertexAttribPointerData_client_proc_t glVertexAttribPointerData;
+	glVertexAttribPointerOffset_client_proc_t glVertexAttribPointerOffset;
+	glDrawElementsOffset_client_proc_t glDrawElementsOffset;
+	glDrawElementsData_client_proc_t glDrawElementsData;
+	glGetCompressedTextureFormats_client_proc_t glGetCompressedTextureFormats;
+	glShaderString_client_proc_t glShaderString;
+	glFinishRoundTrip_client_proc_t glFinishRoundTrip;
+	//Accessors 
+	virtual glActiveTexture_client_proc_t set_glActiveTexture(glActiveTexture_client_proc_t f) { glActiveTexture_client_proc_t retval = glActiveTexture; glActiveTexture = f; return retval;}
+	virtual glAttachShader_client_proc_t set_glAttachShader(glAttachShader_client_proc_t f) { glAttachShader_client_proc_t retval = glAttachShader; glAttachShader = f; return retval;}
+	virtual glBindAttribLocation_client_proc_t set_glBindAttribLocation(glBindAttribLocation_client_proc_t f) { glBindAttribLocation_client_proc_t retval = glBindAttribLocation; glBindAttribLocation = f; return retval;}
+	virtual glBindBuffer_client_proc_t set_glBindBuffer(glBindBuffer_client_proc_t f) { glBindBuffer_client_proc_t retval = glBindBuffer; glBindBuffer = f; return retval;}
+	virtual glBindFramebuffer_client_proc_t set_glBindFramebuffer(glBindFramebuffer_client_proc_t f) { glBindFramebuffer_client_proc_t retval = glBindFramebuffer; glBindFramebuffer = f; return retval;}
+	virtual glBindRenderbuffer_client_proc_t set_glBindRenderbuffer(glBindRenderbuffer_client_proc_t f) { glBindRenderbuffer_client_proc_t retval = glBindRenderbuffer; glBindRenderbuffer = f; return retval;}
+	virtual glBindTexture_client_proc_t set_glBindTexture(glBindTexture_client_proc_t f) { glBindTexture_client_proc_t retval = glBindTexture; glBindTexture = f; return retval;}
+	virtual glBlendColor_client_proc_t set_glBlendColor(glBlendColor_client_proc_t f) { glBlendColor_client_proc_t retval = glBlendColor; glBlendColor = f; return retval;}
+	virtual glBlendEquation_client_proc_t set_glBlendEquation(glBlendEquation_client_proc_t f) { glBlendEquation_client_proc_t retval = glBlendEquation; glBlendEquation = f; return retval;}
+	virtual glBlendEquationSeparate_client_proc_t set_glBlendEquationSeparate(glBlendEquationSeparate_client_proc_t f) { glBlendEquationSeparate_client_proc_t retval = glBlendEquationSeparate; glBlendEquationSeparate = f; return retval;}
+	virtual glBlendFunc_client_proc_t set_glBlendFunc(glBlendFunc_client_proc_t f) { glBlendFunc_client_proc_t retval = glBlendFunc; glBlendFunc = f; return retval;}
+	virtual glBlendFuncSeparate_client_proc_t set_glBlendFuncSeparate(glBlendFuncSeparate_client_proc_t f) { glBlendFuncSeparate_client_proc_t retval = glBlendFuncSeparate; glBlendFuncSeparate = f; return retval;}
+	virtual glBufferData_client_proc_t set_glBufferData(glBufferData_client_proc_t f) { glBufferData_client_proc_t retval = glBufferData; glBufferData = f; return retval;}
+	virtual glBufferSubData_client_proc_t set_glBufferSubData(glBufferSubData_client_proc_t f) { glBufferSubData_client_proc_t retval = glBufferSubData; glBufferSubData = f; return retval;}
+	virtual glCheckFramebufferStatus_client_proc_t set_glCheckFramebufferStatus(glCheckFramebufferStatus_client_proc_t f) { glCheckFramebufferStatus_client_proc_t retval = glCheckFramebufferStatus; glCheckFramebufferStatus = f; return retval;}
+	virtual glClear_client_proc_t set_glClear(glClear_client_proc_t f) { glClear_client_proc_t retval = glClear; glClear = f; return retval;}
+	virtual glClearColor_client_proc_t set_glClearColor(glClearColor_client_proc_t f) { glClearColor_client_proc_t retval = glClearColor; glClearColor = f; return retval;}
+	virtual glClearDepthf_client_proc_t set_glClearDepthf(glClearDepthf_client_proc_t f) { glClearDepthf_client_proc_t retval = glClearDepthf; glClearDepthf = f; return retval;}
+	virtual glClearStencil_client_proc_t set_glClearStencil(glClearStencil_client_proc_t f) { glClearStencil_client_proc_t retval = glClearStencil; glClearStencil = f; return retval;}
+	virtual glColorMask_client_proc_t set_glColorMask(glColorMask_client_proc_t f) { glColorMask_client_proc_t retval = glColorMask; glColorMask = f; return retval;}
+	virtual glCompileShader_client_proc_t set_glCompileShader(glCompileShader_client_proc_t f) { glCompileShader_client_proc_t retval = glCompileShader; glCompileShader = f; return retval;}
+	virtual glCompressedTexImage2D_client_proc_t set_glCompressedTexImage2D(glCompressedTexImage2D_client_proc_t f) { glCompressedTexImage2D_client_proc_t retval = glCompressedTexImage2D; glCompressedTexImage2D = f; return retval;}
+	virtual glCompressedTexSubImage2D_client_proc_t set_glCompressedTexSubImage2D(glCompressedTexSubImage2D_client_proc_t f) { glCompressedTexSubImage2D_client_proc_t retval = glCompressedTexSubImage2D; glCompressedTexSubImage2D = f; return retval;}
+	virtual glCopyTexImage2D_client_proc_t set_glCopyTexImage2D(glCopyTexImage2D_client_proc_t f) { glCopyTexImage2D_client_proc_t retval = glCopyTexImage2D; glCopyTexImage2D = f; return retval;}
+	virtual glCopyTexSubImage2D_client_proc_t set_glCopyTexSubImage2D(glCopyTexSubImage2D_client_proc_t f) { glCopyTexSubImage2D_client_proc_t retval = glCopyTexSubImage2D; glCopyTexSubImage2D = f; return retval;}
+	virtual glCreateProgram_client_proc_t set_glCreateProgram(glCreateProgram_client_proc_t f) { glCreateProgram_client_proc_t retval = glCreateProgram; glCreateProgram = f; return retval;}
+	virtual glCreateShader_client_proc_t set_glCreateShader(glCreateShader_client_proc_t f) { glCreateShader_client_proc_t retval = glCreateShader; glCreateShader = f; return retval;}
+	virtual glCullFace_client_proc_t set_glCullFace(glCullFace_client_proc_t f) { glCullFace_client_proc_t retval = glCullFace; glCullFace = f; return retval;}
+	virtual glDeleteBuffers_client_proc_t set_glDeleteBuffers(glDeleteBuffers_client_proc_t f) { glDeleteBuffers_client_proc_t retval = glDeleteBuffers; glDeleteBuffers = f; return retval;}
+	virtual glDeleteFramebuffers_client_proc_t set_glDeleteFramebuffers(glDeleteFramebuffers_client_proc_t f) { glDeleteFramebuffers_client_proc_t retval = glDeleteFramebuffers; glDeleteFramebuffers = f; return retval;}
+	virtual glDeleteProgram_client_proc_t set_glDeleteProgram(glDeleteProgram_client_proc_t f) { glDeleteProgram_client_proc_t retval = glDeleteProgram; glDeleteProgram = f; return retval;}
+	virtual glDeleteRenderbuffers_client_proc_t set_glDeleteRenderbuffers(glDeleteRenderbuffers_client_proc_t f) { glDeleteRenderbuffers_client_proc_t retval = glDeleteRenderbuffers; glDeleteRenderbuffers = f; return retval;}
+	virtual glDeleteShader_client_proc_t set_glDeleteShader(glDeleteShader_client_proc_t f) { glDeleteShader_client_proc_t retval = glDeleteShader; glDeleteShader = f; return retval;}
+	virtual glDeleteTextures_client_proc_t set_glDeleteTextures(glDeleteTextures_client_proc_t f) { glDeleteTextures_client_proc_t retval = glDeleteTextures; glDeleteTextures = f; return retval;}
+	virtual glDepthFunc_client_proc_t set_glDepthFunc(glDepthFunc_client_proc_t f) { glDepthFunc_client_proc_t retval = glDepthFunc; glDepthFunc = f; return retval;}
+	virtual glDepthMask_client_proc_t set_glDepthMask(glDepthMask_client_proc_t f) { glDepthMask_client_proc_t retval = glDepthMask; glDepthMask = f; return retval;}
+	virtual glDepthRangef_client_proc_t set_glDepthRangef(glDepthRangef_client_proc_t f) { glDepthRangef_client_proc_t retval = glDepthRangef; glDepthRangef = f; return retval;}
+	virtual glDetachShader_client_proc_t set_glDetachShader(glDetachShader_client_proc_t f) { glDetachShader_client_proc_t retval = glDetachShader; glDetachShader = f; return retval;}
+	virtual glDisable_client_proc_t set_glDisable(glDisable_client_proc_t f) { glDisable_client_proc_t retval = glDisable; glDisable = f; return retval;}
+	virtual glDisableVertexAttribArray_client_proc_t set_glDisableVertexAttribArray(glDisableVertexAttribArray_client_proc_t f) { glDisableVertexAttribArray_client_proc_t retval = glDisableVertexAttribArray; glDisableVertexAttribArray = f; return retval;}
+	virtual glDrawArrays_client_proc_t set_glDrawArrays(glDrawArrays_client_proc_t f) { glDrawArrays_client_proc_t retval = glDrawArrays; glDrawArrays = f; return retval;}
+	virtual glDrawElements_client_proc_t set_glDrawElements(glDrawElements_client_proc_t f) { glDrawElements_client_proc_t retval = glDrawElements; glDrawElements = f; return retval;}
+	virtual glEnable_client_proc_t set_glEnable(glEnable_client_proc_t f) { glEnable_client_proc_t retval = glEnable; glEnable = f; return retval;}
+	virtual glEnableVertexAttribArray_client_proc_t set_glEnableVertexAttribArray(glEnableVertexAttribArray_client_proc_t f) { glEnableVertexAttribArray_client_proc_t retval = glEnableVertexAttribArray; glEnableVertexAttribArray = f; return retval;}
+	virtual glFinish_client_proc_t set_glFinish(glFinish_client_proc_t f) { glFinish_client_proc_t retval = glFinish; glFinish = f; return retval;}
+	virtual glFlush_client_proc_t set_glFlush(glFlush_client_proc_t f) { glFlush_client_proc_t retval = glFlush; glFlush = f; return retval;}
+	virtual glFramebufferRenderbuffer_client_proc_t set_glFramebufferRenderbuffer(glFramebufferRenderbuffer_client_proc_t f) { glFramebufferRenderbuffer_client_proc_t retval = glFramebufferRenderbuffer; glFramebufferRenderbuffer = f; return retval;}
+	virtual glFramebufferTexture2D_client_proc_t set_glFramebufferTexture2D(glFramebufferTexture2D_client_proc_t f) { glFramebufferTexture2D_client_proc_t retval = glFramebufferTexture2D; glFramebufferTexture2D = f; return retval;}
+	virtual glFrontFace_client_proc_t set_glFrontFace(glFrontFace_client_proc_t f) { glFrontFace_client_proc_t retval = glFrontFace; glFrontFace = f; return retval;}
+	virtual glGenBuffers_client_proc_t set_glGenBuffers(glGenBuffers_client_proc_t f) { glGenBuffers_client_proc_t retval = glGenBuffers; glGenBuffers = f; return retval;}
+	virtual glGenerateMipmap_client_proc_t set_glGenerateMipmap(glGenerateMipmap_client_proc_t f) { glGenerateMipmap_client_proc_t retval = glGenerateMipmap; glGenerateMipmap = f; return retval;}
+	virtual glGenFramebuffers_client_proc_t set_glGenFramebuffers(glGenFramebuffers_client_proc_t f) { glGenFramebuffers_client_proc_t retval = glGenFramebuffers; glGenFramebuffers = f; return retval;}
+	virtual glGenRenderbuffers_client_proc_t set_glGenRenderbuffers(glGenRenderbuffers_client_proc_t f) { glGenRenderbuffers_client_proc_t retval = glGenRenderbuffers; glGenRenderbuffers = f; return retval;}
+	virtual glGenTextures_client_proc_t set_glGenTextures(glGenTextures_client_proc_t f) { glGenTextures_client_proc_t retval = glGenTextures; glGenTextures = f; return retval;}
+	virtual glGetActiveAttrib_client_proc_t set_glGetActiveAttrib(glGetActiveAttrib_client_proc_t f) { glGetActiveAttrib_client_proc_t retval = glGetActiveAttrib; glGetActiveAttrib = f; return retval;}
+	virtual glGetActiveUniform_client_proc_t set_glGetActiveUniform(glGetActiveUniform_client_proc_t f) { glGetActiveUniform_client_proc_t retval = glGetActiveUniform; glGetActiveUniform = f; return retval;}
+	virtual glGetAttachedShaders_client_proc_t set_glGetAttachedShaders(glGetAttachedShaders_client_proc_t f) { glGetAttachedShaders_client_proc_t retval = glGetAttachedShaders; glGetAttachedShaders = f; return retval;}
+	virtual glGetAttribLocation_client_proc_t set_glGetAttribLocation(glGetAttribLocation_client_proc_t f) { glGetAttribLocation_client_proc_t retval = glGetAttribLocation; glGetAttribLocation = f; return retval;}
+	virtual glGetBooleanv_client_proc_t set_glGetBooleanv(glGetBooleanv_client_proc_t f) { glGetBooleanv_client_proc_t retval = glGetBooleanv; glGetBooleanv = f; return retval;}
+	virtual glGetBufferParameteriv_client_proc_t set_glGetBufferParameteriv(glGetBufferParameteriv_client_proc_t f) { glGetBufferParameteriv_client_proc_t retval = glGetBufferParameteriv; glGetBufferParameteriv = f; return retval;}
+	virtual glGetError_client_proc_t set_glGetError(glGetError_client_proc_t f) { glGetError_client_proc_t retval = glGetError; glGetError = f; return retval;}
+	virtual glGetFloatv_client_proc_t set_glGetFloatv(glGetFloatv_client_proc_t f) { glGetFloatv_client_proc_t retval = glGetFloatv; glGetFloatv = f; return retval;}
+	virtual glGetFramebufferAttachmentParameteriv_client_proc_t set_glGetFramebufferAttachmentParameteriv(glGetFramebufferAttachmentParameteriv_client_proc_t f) { glGetFramebufferAttachmentParameteriv_client_proc_t retval = glGetFramebufferAttachmentParameteriv; glGetFramebufferAttachmentParameteriv = f; return retval;}
+	virtual glGetIntegerv_client_proc_t set_glGetIntegerv(glGetIntegerv_client_proc_t f) { glGetIntegerv_client_proc_t retval = glGetIntegerv; glGetIntegerv = f; return retval;}
+	virtual glGetProgramiv_client_proc_t set_glGetProgramiv(glGetProgramiv_client_proc_t f) { glGetProgramiv_client_proc_t retval = glGetProgramiv; glGetProgramiv = f; return retval;}
+	virtual glGetProgramInfoLog_client_proc_t set_glGetProgramInfoLog(glGetProgramInfoLog_client_proc_t f) { glGetProgramInfoLog_client_proc_t retval = glGetProgramInfoLog; glGetProgramInfoLog = f; return retval;}
+	virtual glGetRenderbufferParameteriv_client_proc_t set_glGetRenderbufferParameteriv(glGetRenderbufferParameteriv_client_proc_t f) { glGetRenderbufferParameteriv_client_proc_t retval = glGetRenderbufferParameteriv; glGetRenderbufferParameteriv = f; return retval;}
+	virtual glGetShaderiv_client_proc_t set_glGetShaderiv(glGetShaderiv_client_proc_t f) { glGetShaderiv_client_proc_t retval = glGetShaderiv; glGetShaderiv = f; return retval;}
+	virtual glGetShaderInfoLog_client_proc_t set_glGetShaderInfoLog(glGetShaderInfoLog_client_proc_t f) { glGetShaderInfoLog_client_proc_t retval = glGetShaderInfoLog; glGetShaderInfoLog = f; return retval;}
+	virtual glGetShaderPrecisionFormat_client_proc_t set_glGetShaderPrecisionFormat(glGetShaderPrecisionFormat_client_proc_t f) { glGetShaderPrecisionFormat_client_proc_t retval = glGetShaderPrecisionFormat; glGetShaderPrecisionFormat = f; return retval;}
+	virtual glGetShaderSource_client_proc_t set_glGetShaderSource(glGetShaderSource_client_proc_t f) { glGetShaderSource_client_proc_t retval = glGetShaderSource; glGetShaderSource = f; return retval;}
+	virtual glGetString_client_proc_t set_glGetString(glGetString_client_proc_t f) { glGetString_client_proc_t retval = glGetString; glGetString = f; return retval;}
+	virtual glGetTexParameterfv_client_proc_t set_glGetTexParameterfv(glGetTexParameterfv_client_proc_t f) { glGetTexParameterfv_client_proc_t retval = glGetTexParameterfv; glGetTexParameterfv = f; return retval;}
+	virtual glGetTexParameteriv_client_proc_t set_glGetTexParameteriv(glGetTexParameteriv_client_proc_t f) { glGetTexParameteriv_client_proc_t retval = glGetTexParameteriv; glGetTexParameteriv = f; return retval;}
+	virtual glGetUniformfv_client_proc_t set_glGetUniformfv(glGetUniformfv_client_proc_t f) { glGetUniformfv_client_proc_t retval = glGetUniformfv; glGetUniformfv = f; return retval;}
+	virtual glGetUniformiv_client_proc_t set_glGetUniformiv(glGetUniformiv_client_proc_t f) { glGetUniformiv_client_proc_t retval = glGetUniformiv; glGetUniformiv = f; return retval;}
+	virtual glGetUniformLocation_client_proc_t set_glGetUniformLocation(glGetUniformLocation_client_proc_t f) { glGetUniformLocation_client_proc_t retval = glGetUniformLocation; glGetUniformLocation = f; return retval;}
+	virtual glGetVertexAttribfv_client_proc_t set_glGetVertexAttribfv(glGetVertexAttribfv_client_proc_t f) { glGetVertexAttribfv_client_proc_t retval = glGetVertexAttribfv; glGetVertexAttribfv = f; return retval;}
+	virtual glGetVertexAttribiv_client_proc_t set_glGetVertexAttribiv(glGetVertexAttribiv_client_proc_t f) { glGetVertexAttribiv_client_proc_t retval = glGetVertexAttribiv; glGetVertexAttribiv = f; return retval;}
+	virtual glGetVertexAttribPointerv_client_proc_t set_glGetVertexAttribPointerv(glGetVertexAttribPointerv_client_proc_t f) { glGetVertexAttribPointerv_client_proc_t retval = glGetVertexAttribPointerv; glGetVertexAttribPointerv = f; return retval;}
+	virtual glHint_client_proc_t set_glHint(glHint_client_proc_t f) { glHint_client_proc_t retval = glHint; glHint = f; return retval;}
+	virtual glIsBuffer_client_proc_t set_glIsBuffer(glIsBuffer_client_proc_t f) { glIsBuffer_client_proc_t retval = glIsBuffer; glIsBuffer = f; return retval;}
+	virtual glIsEnabled_client_proc_t set_glIsEnabled(glIsEnabled_client_proc_t f) { glIsEnabled_client_proc_t retval = glIsEnabled; glIsEnabled = f; return retval;}
+	virtual glIsFramebuffer_client_proc_t set_glIsFramebuffer(glIsFramebuffer_client_proc_t f) { glIsFramebuffer_client_proc_t retval = glIsFramebuffer; glIsFramebuffer = f; return retval;}
+	virtual glIsProgram_client_proc_t set_glIsProgram(glIsProgram_client_proc_t f) { glIsProgram_client_proc_t retval = glIsProgram; glIsProgram = f; return retval;}
+	virtual glIsRenderbuffer_client_proc_t set_glIsRenderbuffer(glIsRenderbuffer_client_proc_t f) { glIsRenderbuffer_client_proc_t retval = glIsRenderbuffer; glIsRenderbuffer = f; return retval;}
+	virtual glIsShader_client_proc_t set_glIsShader(glIsShader_client_proc_t f) { glIsShader_client_proc_t retval = glIsShader; glIsShader = f; return retval;}
+	virtual glIsTexture_client_proc_t set_glIsTexture(glIsTexture_client_proc_t f) { glIsTexture_client_proc_t retval = glIsTexture; glIsTexture = f; return retval;}
+	virtual glLineWidth_client_proc_t set_glLineWidth(glLineWidth_client_proc_t f) { glLineWidth_client_proc_t retval = glLineWidth; glLineWidth = f; return retval;}
+	virtual glLinkProgram_client_proc_t set_glLinkProgram(glLinkProgram_client_proc_t f) { glLinkProgram_client_proc_t retval = glLinkProgram; glLinkProgram = f; return retval;}
+	virtual glPixelStorei_client_proc_t set_glPixelStorei(glPixelStorei_client_proc_t f) { glPixelStorei_client_proc_t retval = glPixelStorei; glPixelStorei = f; return retval;}
+	virtual glPolygonOffset_client_proc_t set_glPolygonOffset(glPolygonOffset_client_proc_t f) { glPolygonOffset_client_proc_t retval = glPolygonOffset; glPolygonOffset = f; return retval;}
+	virtual glReadPixels_client_proc_t set_glReadPixels(glReadPixels_client_proc_t f) { glReadPixels_client_proc_t retval = glReadPixels; glReadPixels = f; return retval;}
+	virtual glReleaseShaderCompiler_client_proc_t set_glReleaseShaderCompiler(glReleaseShaderCompiler_client_proc_t f) { glReleaseShaderCompiler_client_proc_t retval = glReleaseShaderCompiler; glReleaseShaderCompiler = f; return retval;}
+	virtual glRenderbufferStorage_client_proc_t set_glRenderbufferStorage(glRenderbufferStorage_client_proc_t f) { glRenderbufferStorage_client_proc_t retval = glRenderbufferStorage; glRenderbufferStorage = f; return retval;}
+	virtual glSampleCoverage_client_proc_t set_glSampleCoverage(glSampleCoverage_client_proc_t f) { glSampleCoverage_client_proc_t retval = glSampleCoverage; glSampleCoverage = f; return retval;}
+	virtual glScissor_client_proc_t set_glScissor(glScissor_client_proc_t f) { glScissor_client_proc_t retval = glScissor; glScissor = f; return retval;}
+	virtual glShaderBinary_client_proc_t set_glShaderBinary(glShaderBinary_client_proc_t f) { glShaderBinary_client_proc_t retval = glShaderBinary; glShaderBinary = f; return retval;}
+	virtual glShaderSource_client_proc_t set_glShaderSource(glShaderSource_client_proc_t f) { glShaderSource_client_proc_t retval = glShaderSource; glShaderSource = f; return retval;}
+	virtual glStencilFunc_client_proc_t set_glStencilFunc(glStencilFunc_client_proc_t f) { glStencilFunc_client_proc_t retval = glStencilFunc; glStencilFunc = f; return retval;}
+	virtual glStencilFuncSeparate_client_proc_t set_glStencilFuncSeparate(glStencilFuncSeparate_client_proc_t f) { glStencilFuncSeparate_client_proc_t retval = glStencilFuncSeparate; glStencilFuncSeparate = f; return retval;}
+	virtual glStencilMask_client_proc_t set_glStencilMask(glStencilMask_client_proc_t f) { glStencilMask_client_proc_t retval = glStencilMask; glStencilMask = f; return retval;}
+	virtual glStencilMaskSeparate_client_proc_t set_glStencilMaskSeparate(glStencilMaskSeparate_client_proc_t f) { glStencilMaskSeparate_client_proc_t retval = glStencilMaskSeparate; glStencilMaskSeparate = f; return retval;}
+	virtual glStencilOp_client_proc_t set_glStencilOp(glStencilOp_client_proc_t f) { glStencilOp_client_proc_t retval = glStencilOp; glStencilOp = f; return retval;}
+	virtual glStencilOpSeparate_client_proc_t set_glStencilOpSeparate(glStencilOpSeparate_client_proc_t f) { glStencilOpSeparate_client_proc_t retval = glStencilOpSeparate; glStencilOpSeparate = f; return retval;}
+	virtual glTexImage2D_client_proc_t set_glTexImage2D(glTexImage2D_client_proc_t f) { glTexImage2D_client_proc_t retval = glTexImage2D; glTexImage2D = f; return retval;}
+	virtual glTexParameterf_client_proc_t set_glTexParameterf(glTexParameterf_client_proc_t f) { glTexParameterf_client_proc_t retval = glTexParameterf; glTexParameterf = f; return retval;}
+	virtual glTexParameterfv_client_proc_t set_glTexParameterfv(glTexParameterfv_client_proc_t f) { glTexParameterfv_client_proc_t retval = glTexParameterfv; glTexParameterfv = f; return retval;}
+	virtual glTexParameteri_client_proc_t set_glTexParameteri(glTexParameteri_client_proc_t f) { glTexParameteri_client_proc_t retval = glTexParameteri; glTexParameteri = f; return retval;}
+	virtual glTexParameteriv_client_proc_t set_glTexParameteriv(glTexParameteriv_client_proc_t f) { glTexParameteriv_client_proc_t retval = glTexParameteriv; glTexParameteriv = f; return retval;}
+	virtual glTexSubImage2D_client_proc_t set_glTexSubImage2D(glTexSubImage2D_client_proc_t f) { glTexSubImage2D_client_proc_t retval = glTexSubImage2D; glTexSubImage2D = f; return retval;}
+	virtual glUniform1f_client_proc_t set_glUniform1f(glUniform1f_client_proc_t f) { glUniform1f_client_proc_t retval = glUniform1f; glUniform1f = f; return retval;}
+	virtual glUniform1fv_client_proc_t set_glUniform1fv(glUniform1fv_client_proc_t f) { glUniform1fv_client_proc_t retval = glUniform1fv; glUniform1fv = f; return retval;}
+	virtual glUniform1i_client_proc_t set_glUniform1i(glUniform1i_client_proc_t f) { glUniform1i_client_proc_t retval = glUniform1i; glUniform1i = f; return retval;}
+	virtual glUniform1iv_client_proc_t set_glUniform1iv(glUniform1iv_client_proc_t f) { glUniform1iv_client_proc_t retval = glUniform1iv; glUniform1iv = f; return retval;}
+	virtual glUniform2f_client_proc_t set_glUniform2f(glUniform2f_client_proc_t f) { glUniform2f_client_proc_t retval = glUniform2f; glUniform2f = f; return retval;}
+	virtual glUniform2fv_client_proc_t set_glUniform2fv(glUniform2fv_client_proc_t f) { glUniform2fv_client_proc_t retval = glUniform2fv; glUniform2fv = f; return retval;}
+	virtual glUniform2i_client_proc_t set_glUniform2i(glUniform2i_client_proc_t f) { glUniform2i_client_proc_t retval = glUniform2i; glUniform2i = f; return retval;}
+	virtual glUniform2iv_client_proc_t set_glUniform2iv(glUniform2iv_client_proc_t f) { glUniform2iv_client_proc_t retval = glUniform2iv; glUniform2iv = f; return retval;}
+	virtual glUniform3f_client_proc_t set_glUniform3f(glUniform3f_client_proc_t f) { glUniform3f_client_proc_t retval = glUniform3f; glUniform3f = f; return retval;}
+	virtual glUniform3fv_client_proc_t set_glUniform3fv(glUniform3fv_client_proc_t f) { glUniform3fv_client_proc_t retval = glUniform3fv; glUniform3fv = f; return retval;}
+	virtual glUniform3i_client_proc_t set_glUniform3i(glUniform3i_client_proc_t f) { glUniform3i_client_proc_t retval = glUniform3i; glUniform3i = f; return retval;}
+	virtual glUniform3iv_client_proc_t set_glUniform3iv(glUniform3iv_client_proc_t f) { glUniform3iv_client_proc_t retval = glUniform3iv; glUniform3iv = f; return retval;}
+	virtual glUniform4f_client_proc_t set_glUniform4f(glUniform4f_client_proc_t f) { glUniform4f_client_proc_t retval = glUniform4f; glUniform4f = f; return retval;}
+	virtual glUniform4fv_client_proc_t set_glUniform4fv(glUniform4fv_client_proc_t f) { glUniform4fv_client_proc_t retval = glUniform4fv; glUniform4fv = f; return retval;}
+	virtual glUniform4i_client_proc_t set_glUniform4i(glUniform4i_client_proc_t f) { glUniform4i_client_proc_t retval = glUniform4i; glUniform4i = f; return retval;}
+	virtual glUniform4iv_client_proc_t set_glUniform4iv(glUniform4iv_client_proc_t f) { glUniform4iv_client_proc_t retval = glUniform4iv; glUniform4iv = f; return retval;}
+	virtual glUniformMatrix2fv_client_proc_t set_glUniformMatrix2fv(glUniformMatrix2fv_client_proc_t f) { glUniformMatrix2fv_client_proc_t retval = glUniformMatrix2fv; glUniformMatrix2fv = f; return retval;}
+	virtual glUniformMatrix3fv_client_proc_t set_glUniformMatrix3fv(glUniformMatrix3fv_client_proc_t f) { glUniformMatrix3fv_client_proc_t retval = glUniformMatrix3fv; glUniformMatrix3fv = f; return retval;}
+	virtual glUniformMatrix4fv_client_proc_t set_glUniformMatrix4fv(glUniformMatrix4fv_client_proc_t f) { glUniformMatrix4fv_client_proc_t retval = glUniformMatrix4fv; glUniformMatrix4fv = f; return retval;}
+	virtual glUseProgram_client_proc_t set_glUseProgram(glUseProgram_client_proc_t f) { glUseProgram_client_proc_t retval = glUseProgram; glUseProgram = f; return retval;}
+	virtual glValidateProgram_client_proc_t set_glValidateProgram(glValidateProgram_client_proc_t f) { glValidateProgram_client_proc_t retval = glValidateProgram; glValidateProgram = f; return retval;}
+	virtual glVertexAttrib1f_client_proc_t set_glVertexAttrib1f(glVertexAttrib1f_client_proc_t f) { glVertexAttrib1f_client_proc_t retval = glVertexAttrib1f; glVertexAttrib1f = f; return retval;}
+	virtual glVertexAttrib1fv_client_proc_t set_glVertexAttrib1fv(glVertexAttrib1fv_client_proc_t f) { glVertexAttrib1fv_client_proc_t retval = glVertexAttrib1fv; glVertexAttrib1fv = f; return retval;}
+	virtual glVertexAttrib2f_client_proc_t set_glVertexAttrib2f(glVertexAttrib2f_client_proc_t f) { glVertexAttrib2f_client_proc_t retval = glVertexAttrib2f; glVertexAttrib2f = f; return retval;}
+	virtual glVertexAttrib2fv_client_proc_t set_glVertexAttrib2fv(glVertexAttrib2fv_client_proc_t f) { glVertexAttrib2fv_client_proc_t retval = glVertexAttrib2fv; glVertexAttrib2fv = f; return retval;}
+	virtual glVertexAttrib3f_client_proc_t set_glVertexAttrib3f(glVertexAttrib3f_client_proc_t f) { glVertexAttrib3f_client_proc_t retval = glVertexAttrib3f; glVertexAttrib3f = f; return retval;}
+	virtual glVertexAttrib3fv_client_proc_t set_glVertexAttrib3fv(glVertexAttrib3fv_client_proc_t f) { glVertexAttrib3fv_client_proc_t retval = glVertexAttrib3fv; glVertexAttrib3fv = f; return retval;}
+	virtual glVertexAttrib4f_client_proc_t set_glVertexAttrib4f(glVertexAttrib4f_client_proc_t f) { glVertexAttrib4f_client_proc_t retval = glVertexAttrib4f; glVertexAttrib4f = f; return retval;}
+	virtual glVertexAttrib4fv_client_proc_t set_glVertexAttrib4fv(glVertexAttrib4fv_client_proc_t f) { glVertexAttrib4fv_client_proc_t retval = glVertexAttrib4fv; glVertexAttrib4fv = f; return retval;}
+	virtual glVertexAttribPointer_client_proc_t set_glVertexAttribPointer(glVertexAttribPointer_client_proc_t f) { glVertexAttribPointer_client_proc_t retval = glVertexAttribPointer; glVertexAttribPointer = f; return retval;}
+	virtual glViewport_client_proc_t set_glViewport(glViewport_client_proc_t f) { glViewport_client_proc_t retval = glViewport; glViewport = f; return retval;}
+	virtual glEGLImageTargetTexture2DOES_client_proc_t set_glEGLImageTargetTexture2DOES(glEGLImageTargetTexture2DOES_client_proc_t f) { glEGLImageTargetTexture2DOES_client_proc_t retval = glEGLImageTargetTexture2DOES; glEGLImageTargetTexture2DOES = f; return retval;}
+	virtual glEGLImageTargetRenderbufferStorageOES_client_proc_t set_glEGLImageTargetRenderbufferStorageOES(glEGLImageTargetRenderbufferStorageOES_client_proc_t f) { glEGLImageTargetRenderbufferStorageOES_client_proc_t retval = glEGLImageTargetRenderbufferStorageOES; glEGLImageTargetRenderbufferStorageOES = f; return retval;}
+	virtual glGetProgramBinaryOES_client_proc_t set_glGetProgramBinaryOES(glGetProgramBinaryOES_client_proc_t f) { glGetProgramBinaryOES_client_proc_t retval = glGetProgramBinaryOES; glGetProgramBinaryOES = f; return retval;}
+	virtual glProgramBinaryOES_client_proc_t set_glProgramBinaryOES(glProgramBinaryOES_client_proc_t f) { glProgramBinaryOES_client_proc_t retval = glProgramBinaryOES; glProgramBinaryOES = f; return retval;}
+	virtual glMapBufferOES_client_proc_t set_glMapBufferOES(glMapBufferOES_client_proc_t f) { glMapBufferOES_client_proc_t retval = glMapBufferOES; glMapBufferOES = f; return retval;}
+	virtual glUnmapBufferOES_client_proc_t set_glUnmapBufferOES(glUnmapBufferOES_client_proc_t f) { glUnmapBufferOES_client_proc_t retval = glUnmapBufferOES; glUnmapBufferOES = f; return retval;}
+	virtual glTexImage3DOES_client_proc_t set_glTexImage3DOES(glTexImage3DOES_client_proc_t f) { glTexImage3DOES_client_proc_t retval = glTexImage3DOES; glTexImage3DOES = f; return retval;}
+	virtual glTexSubImage3DOES_client_proc_t set_glTexSubImage3DOES(glTexSubImage3DOES_client_proc_t f) { glTexSubImage3DOES_client_proc_t retval = glTexSubImage3DOES; glTexSubImage3DOES = f; return retval;}
+	virtual glCopyTexSubImage3DOES_client_proc_t set_glCopyTexSubImage3DOES(glCopyTexSubImage3DOES_client_proc_t f) { glCopyTexSubImage3DOES_client_proc_t retval = glCopyTexSubImage3DOES; glCopyTexSubImage3DOES = f; return retval;}
+	virtual glCompressedTexImage3DOES_client_proc_t set_glCompressedTexImage3DOES(glCompressedTexImage3DOES_client_proc_t f) { glCompressedTexImage3DOES_client_proc_t retval = glCompressedTexImage3DOES; glCompressedTexImage3DOES = f; return retval;}
+	virtual glCompressedTexSubImage3DOES_client_proc_t set_glCompressedTexSubImage3DOES(glCompressedTexSubImage3DOES_client_proc_t f) { glCompressedTexSubImage3DOES_client_proc_t retval = glCompressedTexSubImage3DOES; glCompressedTexSubImage3DOES = f; return retval;}
+	virtual glFramebufferTexture3DOES_client_proc_t set_glFramebufferTexture3DOES(glFramebufferTexture3DOES_client_proc_t f) { glFramebufferTexture3DOES_client_proc_t retval = glFramebufferTexture3DOES; glFramebufferTexture3DOES = f; return retval;}
+	virtual glBindVertexArrayOES_client_proc_t set_glBindVertexArrayOES(glBindVertexArrayOES_client_proc_t f) { glBindVertexArrayOES_client_proc_t retval = glBindVertexArrayOES; glBindVertexArrayOES = f; return retval;}
+	virtual glDeleteVertexArraysOES_client_proc_t set_glDeleteVertexArraysOES(glDeleteVertexArraysOES_client_proc_t f) { glDeleteVertexArraysOES_client_proc_t retval = glDeleteVertexArraysOES; glDeleteVertexArraysOES = f; return retval;}
+	virtual glGenVertexArraysOES_client_proc_t set_glGenVertexArraysOES(glGenVertexArraysOES_client_proc_t f) { glGenVertexArraysOES_client_proc_t retval = glGenVertexArraysOES; glGenVertexArraysOES = f; return retval;}
+	virtual glIsVertexArrayOES_client_proc_t set_glIsVertexArrayOES(glIsVertexArrayOES_client_proc_t f) { glIsVertexArrayOES_client_proc_t retval = glIsVertexArrayOES; glIsVertexArrayOES = f; return retval;}
+	virtual glDiscardFramebufferEXT_client_proc_t set_glDiscardFramebufferEXT(glDiscardFramebufferEXT_client_proc_t f) { glDiscardFramebufferEXT_client_proc_t retval = glDiscardFramebufferEXT; glDiscardFramebufferEXT = f; return retval;}
+	virtual glMultiDrawArraysEXT_client_proc_t set_glMultiDrawArraysEXT(glMultiDrawArraysEXT_client_proc_t f) { glMultiDrawArraysEXT_client_proc_t retval = glMultiDrawArraysEXT; glMultiDrawArraysEXT = f; return retval;}
+	virtual glMultiDrawElementsEXT_client_proc_t set_glMultiDrawElementsEXT(glMultiDrawElementsEXT_client_proc_t f) { glMultiDrawElementsEXT_client_proc_t retval = glMultiDrawElementsEXT; glMultiDrawElementsEXT = f; return retval;}
+	virtual glGetPerfMonitorGroupsAMD_client_proc_t set_glGetPerfMonitorGroupsAMD(glGetPerfMonitorGroupsAMD_client_proc_t f) { glGetPerfMonitorGroupsAMD_client_proc_t retval = glGetPerfMonitorGroupsAMD; glGetPerfMonitorGroupsAMD = f; return retval;}
+	virtual glGetPerfMonitorCountersAMD_client_proc_t set_glGetPerfMonitorCountersAMD(glGetPerfMonitorCountersAMD_client_proc_t f) { glGetPerfMonitorCountersAMD_client_proc_t retval = glGetPerfMonitorCountersAMD; glGetPerfMonitorCountersAMD = f; return retval;}
+	virtual glGetPerfMonitorGroupStringAMD_client_proc_t set_glGetPerfMonitorGroupStringAMD(glGetPerfMonitorGroupStringAMD_client_proc_t f) { glGetPerfMonitorGroupStringAMD_client_proc_t retval = glGetPerfMonitorGroupStringAMD; glGetPerfMonitorGroupStringAMD = f; return retval;}
+	virtual glGetPerfMonitorCounterStringAMD_client_proc_t set_glGetPerfMonitorCounterStringAMD(glGetPerfMonitorCounterStringAMD_client_proc_t f) { glGetPerfMonitorCounterStringAMD_client_proc_t retval = glGetPerfMonitorCounterStringAMD; glGetPerfMonitorCounterStringAMD = f; return retval;}
+	virtual glGetPerfMonitorCounterInfoAMD_client_proc_t set_glGetPerfMonitorCounterInfoAMD(glGetPerfMonitorCounterInfoAMD_client_proc_t f) { glGetPerfMonitorCounterInfoAMD_client_proc_t retval = glGetPerfMonitorCounterInfoAMD; glGetPerfMonitorCounterInfoAMD = f; return retval;}
+	virtual glGenPerfMonitorsAMD_client_proc_t set_glGenPerfMonitorsAMD(glGenPerfMonitorsAMD_client_proc_t f) { glGenPerfMonitorsAMD_client_proc_t retval = glGenPerfMonitorsAMD; glGenPerfMonitorsAMD = f; return retval;}
+	virtual glDeletePerfMonitorsAMD_client_proc_t set_glDeletePerfMonitorsAMD(glDeletePerfMonitorsAMD_client_proc_t f) { glDeletePerfMonitorsAMD_client_proc_t retval = glDeletePerfMonitorsAMD; glDeletePerfMonitorsAMD = f; return retval;}
+	virtual glSelectPerfMonitorCountersAMD_client_proc_t set_glSelectPerfMonitorCountersAMD(glSelectPerfMonitorCountersAMD_client_proc_t f) { glSelectPerfMonitorCountersAMD_client_proc_t retval = glSelectPerfMonitorCountersAMD; glSelectPerfMonitorCountersAMD = f; return retval;}
+	virtual glBeginPerfMonitorAMD_client_proc_t set_glBeginPerfMonitorAMD(glBeginPerfMonitorAMD_client_proc_t f) { glBeginPerfMonitorAMD_client_proc_t retval = glBeginPerfMonitorAMD; glBeginPerfMonitorAMD = f; return retval;}
+	virtual glEndPerfMonitorAMD_client_proc_t set_glEndPerfMonitorAMD(glEndPerfMonitorAMD_client_proc_t f) { glEndPerfMonitorAMD_client_proc_t retval = glEndPerfMonitorAMD; glEndPerfMonitorAMD = f; return retval;}
+	virtual glGetPerfMonitorCounterDataAMD_client_proc_t set_glGetPerfMonitorCounterDataAMD(glGetPerfMonitorCounterDataAMD_client_proc_t f) { glGetPerfMonitorCounterDataAMD_client_proc_t retval = glGetPerfMonitorCounterDataAMD; glGetPerfMonitorCounterDataAMD = f; return retval;}
+	virtual glRenderbufferStorageMultisampleIMG_client_proc_t set_glRenderbufferStorageMultisampleIMG(glRenderbufferStorageMultisampleIMG_client_proc_t f) { glRenderbufferStorageMultisampleIMG_client_proc_t retval = glRenderbufferStorageMultisampleIMG; glRenderbufferStorageMultisampleIMG = f; return retval;}
+	virtual glFramebufferTexture2DMultisampleIMG_client_proc_t set_glFramebufferTexture2DMultisampleIMG(glFramebufferTexture2DMultisampleIMG_client_proc_t f) { glFramebufferTexture2DMultisampleIMG_client_proc_t retval = glFramebufferTexture2DMultisampleIMG; glFramebufferTexture2DMultisampleIMG = f; return retval;}
+	virtual glDeleteFencesNV_client_proc_t set_glDeleteFencesNV(glDeleteFencesNV_client_proc_t f) { glDeleteFencesNV_client_proc_t retval = glDeleteFencesNV; glDeleteFencesNV = f; return retval;}
+	virtual glGenFencesNV_client_proc_t set_glGenFencesNV(glGenFencesNV_client_proc_t f) { glGenFencesNV_client_proc_t retval = glGenFencesNV; glGenFencesNV = f; return retval;}
+	virtual glIsFenceNV_client_proc_t set_glIsFenceNV(glIsFenceNV_client_proc_t f) { glIsFenceNV_client_proc_t retval = glIsFenceNV; glIsFenceNV = f; return retval;}
+	virtual glTestFenceNV_client_proc_t set_glTestFenceNV(glTestFenceNV_client_proc_t f) { glTestFenceNV_client_proc_t retval = glTestFenceNV; glTestFenceNV = f; return retval;}
+	virtual glGetFenceivNV_client_proc_t set_glGetFenceivNV(glGetFenceivNV_client_proc_t f) { glGetFenceivNV_client_proc_t retval = glGetFenceivNV; glGetFenceivNV = f; return retval;}
+	virtual glFinishFenceNV_client_proc_t set_glFinishFenceNV(glFinishFenceNV_client_proc_t f) { glFinishFenceNV_client_proc_t retval = glFinishFenceNV; glFinishFenceNV = f; return retval;}
+	virtual glSetFenceNV_client_proc_t set_glSetFenceNV(glSetFenceNV_client_proc_t f) { glSetFenceNV_client_proc_t retval = glSetFenceNV; glSetFenceNV = f; return retval;}
+	virtual glCoverageMaskNV_client_proc_t set_glCoverageMaskNV(glCoverageMaskNV_client_proc_t f) { glCoverageMaskNV_client_proc_t retval = glCoverageMaskNV; glCoverageMaskNV = f; return retval;}
+	virtual glCoverageOperationNV_client_proc_t set_glCoverageOperationNV(glCoverageOperationNV_client_proc_t f) { glCoverageOperationNV_client_proc_t retval = glCoverageOperationNV; glCoverageOperationNV = f; return retval;}
+	virtual glGetDriverControlsQCOM_client_proc_t set_glGetDriverControlsQCOM(glGetDriverControlsQCOM_client_proc_t f) { glGetDriverControlsQCOM_client_proc_t retval = glGetDriverControlsQCOM; glGetDriverControlsQCOM = f; return retval;}
+	virtual glGetDriverControlStringQCOM_client_proc_t set_glGetDriverControlStringQCOM(glGetDriverControlStringQCOM_client_proc_t f) { glGetDriverControlStringQCOM_client_proc_t retval = glGetDriverControlStringQCOM; glGetDriverControlStringQCOM = f; return retval;}
+	virtual glEnableDriverControlQCOM_client_proc_t set_glEnableDriverControlQCOM(glEnableDriverControlQCOM_client_proc_t f) { glEnableDriverControlQCOM_client_proc_t retval = glEnableDriverControlQCOM; glEnableDriverControlQCOM = f; return retval;}
+	virtual glDisableDriverControlQCOM_client_proc_t set_glDisableDriverControlQCOM(glDisableDriverControlQCOM_client_proc_t f) { glDisableDriverControlQCOM_client_proc_t retval = glDisableDriverControlQCOM; glDisableDriverControlQCOM = f; return retval;}
+	virtual glExtGetTexturesQCOM_client_proc_t set_glExtGetTexturesQCOM(glExtGetTexturesQCOM_client_proc_t f) { glExtGetTexturesQCOM_client_proc_t retval = glExtGetTexturesQCOM; glExtGetTexturesQCOM = f; return retval;}
+	virtual glExtGetBuffersQCOM_client_proc_t set_glExtGetBuffersQCOM(glExtGetBuffersQCOM_client_proc_t f) { glExtGetBuffersQCOM_client_proc_t retval = glExtGetBuffersQCOM; glExtGetBuffersQCOM = f; return retval;}
+	virtual glExtGetRenderbuffersQCOM_client_proc_t set_glExtGetRenderbuffersQCOM(glExtGetRenderbuffersQCOM_client_proc_t f) { glExtGetRenderbuffersQCOM_client_proc_t retval = glExtGetRenderbuffersQCOM; glExtGetRenderbuffersQCOM = f; return retval;}
+	virtual glExtGetFramebuffersQCOM_client_proc_t set_glExtGetFramebuffersQCOM(glExtGetFramebuffersQCOM_client_proc_t f) { glExtGetFramebuffersQCOM_client_proc_t retval = glExtGetFramebuffersQCOM; glExtGetFramebuffersQCOM = f; return retval;}
+	virtual glExtGetTexLevelParameterivQCOM_client_proc_t set_glExtGetTexLevelParameterivQCOM(glExtGetTexLevelParameterivQCOM_client_proc_t f) { glExtGetTexLevelParameterivQCOM_client_proc_t retval = glExtGetTexLevelParameterivQCOM; glExtGetTexLevelParameterivQCOM = f; return retval;}
+	virtual glExtTexObjectStateOverrideiQCOM_client_proc_t set_glExtTexObjectStateOverrideiQCOM(glExtTexObjectStateOverrideiQCOM_client_proc_t f) { glExtTexObjectStateOverrideiQCOM_client_proc_t retval = glExtTexObjectStateOverrideiQCOM; glExtTexObjectStateOverrideiQCOM = f; return retval;}
+	virtual glExtGetTexSubImageQCOM_client_proc_t set_glExtGetTexSubImageQCOM(glExtGetTexSubImageQCOM_client_proc_t f) { glExtGetTexSubImageQCOM_client_proc_t retval = glExtGetTexSubImageQCOM; glExtGetTexSubImageQCOM = f; return retval;}
+	virtual glExtGetBufferPointervQCOM_client_proc_t set_glExtGetBufferPointervQCOM(glExtGetBufferPointervQCOM_client_proc_t f) { glExtGetBufferPointervQCOM_client_proc_t retval = glExtGetBufferPointervQCOM; glExtGetBufferPointervQCOM = f; return retval;}
+	virtual glExtGetShadersQCOM_client_proc_t set_glExtGetShadersQCOM(glExtGetShadersQCOM_client_proc_t f) { glExtGetShadersQCOM_client_proc_t retval = glExtGetShadersQCOM; glExtGetShadersQCOM = f; return retval;}
+	virtual glExtGetProgramsQCOM_client_proc_t set_glExtGetProgramsQCOM(glExtGetProgramsQCOM_client_proc_t f) { glExtGetProgramsQCOM_client_proc_t retval = glExtGetProgramsQCOM; glExtGetProgramsQCOM = f; return retval;}
+	virtual glExtIsProgramBinaryQCOM_client_proc_t set_glExtIsProgramBinaryQCOM(glExtIsProgramBinaryQCOM_client_proc_t f) { glExtIsProgramBinaryQCOM_client_proc_t retval = glExtIsProgramBinaryQCOM; glExtIsProgramBinaryQCOM = f; return retval;}
+	virtual glExtGetProgramBinarySourceQCOM_client_proc_t set_glExtGetProgramBinarySourceQCOM(glExtGetProgramBinarySourceQCOM_client_proc_t f) { glExtGetProgramBinarySourceQCOM_client_proc_t retval = glExtGetProgramBinarySourceQCOM; glExtGetProgramBinarySourceQCOM = f; return retval;}
+	virtual glStartTilingQCOM_client_proc_t set_glStartTilingQCOM(glStartTilingQCOM_client_proc_t f) { glStartTilingQCOM_client_proc_t retval = glStartTilingQCOM; glStartTilingQCOM = f; return retval;}
+	virtual glEndTilingQCOM_client_proc_t set_glEndTilingQCOM(glEndTilingQCOM_client_proc_t f) { glEndTilingQCOM_client_proc_t retval = glEndTilingQCOM; glEndTilingQCOM = f; return retval;}
+	virtual glVertexAttribPointerData_client_proc_t set_glVertexAttribPointerData(glVertexAttribPointerData_client_proc_t f) { glVertexAttribPointerData_client_proc_t retval = glVertexAttribPointerData; glVertexAttribPointerData = f; return retval;}
+	virtual glVertexAttribPointerOffset_client_proc_t set_glVertexAttribPointerOffset(glVertexAttribPointerOffset_client_proc_t f) { glVertexAttribPointerOffset_client_proc_t retval = glVertexAttribPointerOffset; glVertexAttribPointerOffset = f; return retval;}
+	virtual glDrawElementsOffset_client_proc_t set_glDrawElementsOffset(glDrawElementsOffset_client_proc_t f) { glDrawElementsOffset_client_proc_t retval = glDrawElementsOffset; glDrawElementsOffset = f; return retval;}
+	virtual glDrawElementsData_client_proc_t set_glDrawElementsData(glDrawElementsData_client_proc_t f) { glDrawElementsData_client_proc_t retval = glDrawElementsData; glDrawElementsData = f; return retval;}
+	virtual glGetCompressedTextureFormats_client_proc_t set_glGetCompressedTextureFormats(glGetCompressedTextureFormats_client_proc_t f) { glGetCompressedTextureFormats_client_proc_t retval = glGetCompressedTextureFormats; glGetCompressedTextureFormats = f; return retval;}
+	virtual glShaderString_client_proc_t set_glShaderString(glShaderString_client_proc_t f) { glShaderString_client_proc_t retval = glShaderString; glShaderString = f; return retval;}
+	virtual glFinishRoundTrip_client_proc_t set_glFinishRoundTrip(glFinishRoundTrip_client_proc_t f) { glFinishRoundTrip_client_proc_t retval = glFinishRoundTrip; glFinishRoundTrip = f; return retval;}
+	 virtual ~gl2_client_context_t() {}
+
+	typedef gl2_client_context_t *CONTEXT_ACCESSOR_TYPE(void);
+	static void setContextAccessor(CONTEXT_ACCESSOR_TYPE *f);
+	int initDispatchByName( void *(*getProc)(const char *name, void *userData), void *userData);
+	virtual void setError(unsigned int  error){};
+	virtual unsigned int getError(){ return 0; };
+};
+
+#endif
diff --git a/opengl/system/GLESv2_enc/gl2_client_proc.h b/opengl/system/GLESv2_enc/gl2_client_proc.h
new file mode 100644
index 0000000..4eeda70
--- /dev/null
+++ b/opengl/system/GLESv2_enc/gl2_client_proc.h
@@ -0,0 +1,222 @@
+// Generated Code - DO NOT EDIT !!
+// generated by 'emugen'
+#ifndef __gl2_client_proc_t_h
+#define __gl2_client_proc_t_h
+
+
+
+#include "gl2_types.h"
+#ifndef gl2_APIENTRY
+#define gl2_APIENTRY
+#endif
+typedef void (gl2_APIENTRY *glActiveTexture_client_proc_t) (void * ctx, GLenum);
+typedef void (gl2_APIENTRY *glAttachShader_client_proc_t) (void * ctx, GLuint, GLuint);
+typedef void (gl2_APIENTRY *glBindAttribLocation_client_proc_t) (void * ctx, GLuint, GLuint, const GLchar*);
+typedef void (gl2_APIENTRY *glBindBuffer_client_proc_t) (void * ctx, GLenum, GLuint);
+typedef void (gl2_APIENTRY *glBindFramebuffer_client_proc_t) (void * ctx, GLenum, GLuint);
+typedef void (gl2_APIENTRY *glBindRenderbuffer_client_proc_t) (void * ctx, GLenum, GLuint);
+typedef void (gl2_APIENTRY *glBindTexture_client_proc_t) (void * ctx, GLenum, GLuint);
+typedef void (gl2_APIENTRY *glBlendColor_client_proc_t) (void * ctx, GLclampf, GLclampf, GLclampf, GLclampf);
+typedef void (gl2_APIENTRY *glBlendEquation_client_proc_t) (void * ctx, GLenum);
+typedef void (gl2_APIENTRY *glBlendEquationSeparate_client_proc_t) (void * ctx, GLenum, GLenum);
+typedef void (gl2_APIENTRY *glBlendFunc_client_proc_t) (void * ctx, GLenum, GLenum);
+typedef void (gl2_APIENTRY *glBlendFuncSeparate_client_proc_t) (void * ctx, GLenum, GLenum, GLenum, GLenum);
+typedef void (gl2_APIENTRY *glBufferData_client_proc_t) (void * ctx, GLenum, GLsizeiptr, const GLvoid*, GLenum);
+typedef void (gl2_APIENTRY *glBufferSubData_client_proc_t) (void * ctx, GLenum, GLintptr, GLsizeiptr, const GLvoid*);
+typedef GLenum (gl2_APIENTRY *glCheckFramebufferStatus_client_proc_t) (void * ctx, GLenum);
+typedef void (gl2_APIENTRY *glClear_client_proc_t) (void * ctx, GLbitfield);
+typedef void (gl2_APIENTRY *glClearColor_client_proc_t) (void * ctx, GLclampf, GLclampf, GLclampf, GLclampf);
+typedef void (gl2_APIENTRY *glClearDepthf_client_proc_t) (void * ctx, GLclampf);
+typedef void (gl2_APIENTRY *glClearStencil_client_proc_t) (void * ctx, GLint);
+typedef void (gl2_APIENTRY *glColorMask_client_proc_t) (void * ctx, GLboolean, GLboolean, GLboolean, GLboolean);
+typedef void (gl2_APIENTRY *glCompileShader_client_proc_t) (void * ctx, GLuint);
+typedef void (gl2_APIENTRY *glCompressedTexImage2D_client_proc_t) (void * ctx, GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid*);
+typedef void (gl2_APIENTRY *glCompressedTexSubImage2D_client_proc_t) (void * ctx, GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid*);
+typedef void (gl2_APIENTRY *glCopyTexImage2D_client_proc_t) (void * ctx, GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint);
+typedef void (gl2_APIENTRY *glCopyTexSubImage2D_client_proc_t) (void * ctx, GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei);
+typedef GLuint (gl2_APIENTRY *glCreateProgram_client_proc_t) (void * ctx);
+typedef GLuint (gl2_APIENTRY *glCreateShader_client_proc_t) (void * ctx, GLenum);
+typedef void (gl2_APIENTRY *glCullFace_client_proc_t) (void * ctx, GLenum);
+typedef void (gl2_APIENTRY *glDeleteBuffers_client_proc_t) (void * ctx, GLsizei, const GLuint*);
+typedef void (gl2_APIENTRY *glDeleteFramebuffers_client_proc_t) (void * ctx, GLsizei, const GLuint*);
+typedef void (gl2_APIENTRY *glDeleteProgram_client_proc_t) (void * ctx, GLuint);
+typedef void (gl2_APIENTRY *glDeleteRenderbuffers_client_proc_t) (void * ctx, GLsizei, const GLuint*);
+typedef void (gl2_APIENTRY *glDeleteShader_client_proc_t) (void * ctx, GLuint);
+typedef void (gl2_APIENTRY *glDeleteTextures_client_proc_t) (void * ctx, GLsizei, const GLuint*);
+typedef void (gl2_APIENTRY *glDepthFunc_client_proc_t) (void * ctx, GLenum);
+typedef void (gl2_APIENTRY *glDepthMask_client_proc_t) (void * ctx, GLboolean);
+typedef void (gl2_APIENTRY *glDepthRangef_client_proc_t) (void * ctx, GLclampf, GLclampf);
+typedef void (gl2_APIENTRY *glDetachShader_client_proc_t) (void * ctx, GLuint, GLuint);
+typedef void (gl2_APIENTRY *glDisable_client_proc_t) (void * ctx, GLenum);
+typedef void (gl2_APIENTRY *glDisableVertexAttribArray_client_proc_t) (void * ctx, GLuint);
+typedef void (gl2_APIENTRY *glDrawArrays_client_proc_t) (void * ctx, GLenum, GLint, GLsizei);
+typedef void (gl2_APIENTRY *glDrawElements_client_proc_t) (void * ctx, GLenum, GLsizei, GLenum, const GLvoid*);
+typedef void (gl2_APIENTRY *glEnable_client_proc_t) (void * ctx, GLenum);
+typedef void (gl2_APIENTRY *glEnableVertexAttribArray_client_proc_t) (void * ctx, GLuint);
+typedef void (gl2_APIENTRY *glFinish_client_proc_t) (void * ctx);
+typedef void (gl2_APIENTRY *glFlush_client_proc_t) (void * ctx);
+typedef void (gl2_APIENTRY *glFramebufferRenderbuffer_client_proc_t) (void * ctx, GLenum, GLenum, GLenum, GLuint);
+typedef void (gl2_APIENTRY *glFramebufferTexture2D_client_proc_t) (void * ctx, GLenum, GLenum, GLenum, GLuint, GLint);
+typedef void (gl2_APIENTRY *glFrontFace_client_proc_t) (void * ctx, GLenum);
+typedef void (gl2_APIENTRY *glGenBuffers_client_proc_t) (void * ctx, GLsizei, GLuint*);
+typedef void (gl2_APIENTRY *glGenerateMipmap_client_proc_t) (void * ctx, GLenum);
+typedef void (gl2_APIENTRY *glGenFramebuffers_client_proc_t) (void * ctx, GLsizei, GLuint*);
+typedef void (gl2_APIENTRY *glGenRenderbuffers_client_proc_t) (void * ctx, GLsizei, GLuint*);
+typedef void (gl2_APIENTRY *glGenTextures_client_proc_t) (void * ctx, GLsizei, GLuint*);
+typedef void (gl2_APIENTRY *glGetActiveAttrib_client_proc_t) (void * ctx, GLuint, GLuint, GLsizei, GLsizei*, GLint*, GLenum*, GLchar*);
+typedef void (gl2_APIENTRY *glGetActiveUniform_client_proc_t) (void * ctx, GLuint, GLuint, GLsizei, GLsizei*, GLint*, GLenum*, GLchar*);
+typedef void (gl2_APIENTRY *glGetAttachedShaders_client_proc_t) (void * ctx, GLuint, GLsizei, GLsizei*, GLuint*);
+typedef int (gl2_APIENTRY *glGetAttribLocation_client_proc_t) (void * ctx, GLuint, const GLchar*);
+typedef void (gl2_APIENTRY *glGetBooleanv_client_proc_t) (void * ctx, GLenum, GLboolean*);
+typedef void (gl2_APIENTRY *glGetBufferParameteriv_client_proc_t) (void * ctx, GLenum, GLenum, GLint*);
+typedef GLenum (gl2_APIENTRY *glGetError_client_proc_t) (void * ctx);
+typedef void (gl2_APIENTRY *glGetFloatv_client_proc_t) (void * ctx, GLenum, GLfloat*);
+typedef void (gl2_APIENTRY *glGetFramebufferAttachmentParameteriv_client_proc_t) (void * ctx, GLenum, GLenum, GLenum, GLint*);
+typedef void (gl2_APIENTRY *glGetIntegerv_client_proc_t) (void * ctx, GLenum, GLint*);
+typedef void (gl2_APIENTRY *glGetProgramiv_client_proc_t) (void * ctx, GLuint, GLenum, GLint*);
+typedef void (gl2_APIENTRY *glGetProgramInfoLog_client_proc_t) (void * ctx, GLuint, GLsizei, GLsizei*, GLchar*);
+typedef void (gl2_APIENTRY *glGetRenderbufferParameteriv_client_proc_t) (void * ctx, GLenum, GLenum, GLint*);
+typedef void (gl2_APIENTRY *glGetShaderiv_client_proc_t) (void * ctx, GLuint, GLenum, GLint*);
+typedef void (gl2_APIENTRY *glGetShaderInfoLog_client_proc_t) (void * ctx, GLuint, GLsizei, GLsizei*, GLchar*);
+typedef void (gl2_APIENTRY *glGetShaderPrecisionFormat_client_proc_t) (void * ctx, GLenum, GLenum, GLint*, GLint*);
+typedef void (gl2_APIENTRY *glGetShaderSource_client_proc_t) (void * ctx, GLuint, GLsizei, GLsizei*, GLchar*);
+typedef const GLubyte* (gl2_APIENTRY *glGetString_client_proc_t) (void * ctx, GLenum);
+typedef void (gl2_APIENTRY *glGetTexParameterfv_client_proc_t) (void * ctx, GLenum, GLenum, GLfloat*);
+typedef void (gl2_APIENTRY *glGetTexParameteriv_client_proc_t) (void * ctx, GLenum, GLenum, GLint*);
+typedef void (gl2_APIENTRY *glGetUniformfv_client_proc_t) (void * ctx, GLuint, GLint, GLfloat*);
+typedef void (gl2_APIENTRY *glGetUniformiv_client_proc_t) (void * ctx, GLuint, GLint, GLint*);
+typedef int (gl2_APIENTRY *glGetUniformLocation_client_proc_t) (void * ctx, GLuint, const GLchar*);
+typedef void (gl2_APIENTRY *glGetVertexAttribfv_client_proc_t) (void * ctx, GLuint, GLenum, GLfloat*);
+typedef void (gl2_APIENTRY *glGetVertexAttribiv_client_proc_t) (void * ctx, GLuint, GLenum, GLint*);
+typedef void (gl2_APIENTRY *glGetVertexAttribPointerv_client_proc_t) (void * ctx, GLuint, GLenum, GLvoid**);
+typedef void (gl2_APIENTRY *glHint_client_proc_t) (void * ctx, GLenum, GLenum);
+typedef GLboolean (gl2_APIENTRY *glIsBuffer_client_proc_t) (void * ctx, GLuint);
+typedef GLboolean (gl2_APIENTRY *glIsEnabled_client_proc_t) (void * ctx, GLenum);
+typedef GLboolean (gl2_APIENTRY *glIsFramebuffer_client_proc_t) (void * ctx, GLuint);
+typedef GLboolean (gl2_APIENTRY *glIsProgram_client_proc_t) (void * ctx, GLuint);
+typedef GLboolean (gl2_APIENTRY *glIsRenderbuffer_client_proc_t) (void * ctx, GLuint);
+typedef GLboolean (gl2_APIENTRY *glIsShader_client_proc_t) (void * ctx, GLuint);
+typedef GLboolean (gl2_APIENTRY *glIsTexture_client_proc_t) (void * ctx, GLuint);
+typedef void (gl2_APIENTRY *glLineWidth_client_proc_t) (void * ctx, GLfloat);
+typedef void (gl2_APIENTRY *glLinkProgram_client_proc_t) (void * ctx, GLuint);
+typedef void (gl2_APIENTRY *glPixelStorei_client_proc_t) (void * ctx, GLenum, GLint);
+typedef void (gl2_APIENTRY *glPolygonOffset_client_proc_t) (void * ctx, GLfloat, GLfloat);
+typedef void (gl2_APIENTRY *glReadPixels_client_proc_t) (void * ctx, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, GLvoid*);
+typedef void (gl2_APIENTRY *glReleaseShaderCompiler_client_proc_t) (void * ctx);
+typedef void (gl2_APIENTRY *glRenderbufferStorage_client_proc_t) (void * ctx, GLenum, GLenum, GLsizei, GLsizei);
+typedef void (gl2_APIENTRY *glSampleCoverage_client_proc_t) (void * ctx, GLclampf, GLboolean);
+typedef void (gl2_APIENTRY *glScissor_client_proc_t) (void * ctx, GLint, GLint, GLsizei, GLsizei);
+typedef void (gl2_APIENTRY *glShaderBinary_client_proc_t) (void * ctx, GLsizei, const GLuint*, GLenum, const GLvoid*, GLsizei);
+typedef void (gl2_APIENTRY *glShaderSource_client_proc_t) (void * ctx, GLuint, GLsizei, const GLchar* const*, const GLint*);
+typedef void (gl2_APIENTRY *glStencilFunc_client_proc_t) (void * ctx, GLenum, GLint, GLuint);
+typedef void (gl2_APIENTRY *glStencilFuncSeparate_client_proc_t) (void * ctx, GLenum, GLenum, GLint, GLuint);
+typedef void (gl2_APIENTRY *glStencilMask_client_proc_t) (void * ctx, GLuint);
+typedef void (gl2_APIENTRY *glStencilMaskSeparate_client_proc_t) (void * ctx, GLenum, GLuint);
+typedef void (gl2_APIENTRY *glStencilOp_client_proc_t) (void * ctx, GLenum, GLenum, GLenum);
+typedef void (gl2_APIENTRY *glStencilOpSeparate_client_proc_t) (void * ctx, GLenum, GLenum, GLenum, GLenum);
+typedef void (gl2_APIENTRY *glTexImage2D_client_proc_t) (void * ctx, GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid*);
+typedef void (gl2_APIENTRY *glTexParameterf_client_proc_t) (void * ctx, GLenum, GLenum, GLfloat);
+typedef void (gl2_APIENTRY *glTexParameterfv_client_proc_t) (void * ctx, GLenum, GLenum, const GLfloat*);
+typedef void (gl2_APIENTRY *glTexParameteri_client_proc_t) (void * ctx, GLenum, GLenum, GLint);
+typedef void (gl2_APIENTRY *glTexParameteriv_client_proc_t) (void * ctx, GLenum, GLenum, const GLint*);
+typedef void (gl2_APIENTRY *glTexSubImage2D_client_proc_t) (void * ctx, GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid*);
+typedef void (gl2_APIENTRY *glUniform1f_client_proc_t) (void * ctx, GLint, GLfloat);
+typedef void (gl2_APIENTRY *glUniform1fv_client_proc_t) (void * ctx, GLint, GLsizei, const GLfloat*);
+typedef void (gl2_APIENTRY *glUniform1i_client_proc_t) (void * ctx, GLint, GLint);
+typedef void (gl2_APIENTRY *glUniform1iv_client_proc_t) (void * ctx, GLint, GLsizei, const GLint*);
+typedef void (gl2_APIENTRY *glUniform2f_client_proc_t) (void * ctx, GLint, GLfloat, GLfloat);
+typedef void (gl2_APIENTRY *glUniform2fv_client_proc_t) (void * ctx, GLint, GLsizei, const GLfloat*);
+typedef void (gl2_APIENTRY *glUniform2i_client_proc_t) (void * ctx, GLint, GLint, GLint);
+typedef void (gl2_APIENTRY *glUniform2iv_client_proc_t) (void * ctx, GLint, GLsizei, const GLint*);
+typedef void (gl2_APIENTRY *glUniform3f_client_proc_t) (void * ctx, GLint, GLfloat, GLfloat, GLfloat);
+typedef void (gl2_APIENTRY *glUniform3fv_client_proc_t) (void * ctx, GLint, GLsizei, const GLfloat*);
+typedef void (gl2_APIENTRY *glUniform3i_client_proc_t) (void * ctx, GLint, GLint, GLint, GLint);
+typedef void (gl2_APIENTRY *glUniform3iv_client_proc_t) (void * ctx, GLint, GLsizei, const GLint*);
+typedef void (gl2_APIENTRY *glUniform4f_client_proc_t) (void * ctx, GLint, GLfloat, GLfloat, GLfloat, GLfloat);
+typedef void (gl2_APIENTRY *glUniform4fv_client_proc_t) (void * ctx, GLint, GLsizei, const GLfloat*);
+typedef void (gl2_APIENTRY *glUniform4i_client_proc_t) (void * ctx, GLint, GLint, GLint, GLint, GLint);
+typedef void (gl2_APIENTRY *glUniform4iv_client_proc_t) (void * ctx, GLint, GLsizei, const GLint*);
+typedef void (gl2_APIENTRY *glUniformMatrix2fv_client_proc_t) (void * ctx, GLint, GLsizei, GLboolean, const GLfloat*);
+typedef void (gl2_APIENTRY *glUniformMatrix3fv_client_proc_t) (void * ctx, GLint, GLsizei, GLboolean, const GLfloat*);
+typedef void (gl2_APIENTRY *glUniformMatrix4fv_client_proc_t) (void * ctx, GLint, GLsizei, GLboolean, const GLfloat*);
+typedef void (gl2_APIENTRY *glUseProgram_client_proc_t) (void * ctx, GLuint);
+typedef void (gl2_APIENTRY *glValidateProgram_client_proc_t) (void * ctx, GLuint);
+typedef void (gl2_APIENTRY *glVertexAttrib1f_client_proc_t) (void * ctx, GLuint, GLfloat);
+typedef void (gl2_APIENTRY *glVertexAttrib1fv_client_proc_t) (void * ctx, GLuint, const GLfloat*);
+typedef void (gl2_APIENTRY *glVertexAttrib2f_client_proc_t) (void * ctx, GLuint, GLfloat, GLfloat);
+typedef void (gl2_APIENTRY *glVertexAttrib2fv_client_proc_t) (void * ctx, GLuint, const GLfloat*);
+typedef void (gl2_APIENTRY *glVertexAttrib3f_client_proc_t) (void * ctx, GLuint, GLfloat, GLfloat, GLfloat);
+typedef void (gl2_APIENTRY *glVertexAttrib3fv_client_proc_t) (void * ctx, GLuint, const GLfloat*);
+typedef void (gl2_APIENTRY *glVertexAttrib4f_client_proc_t) (void * ctx, GLuint, GLfloat, GLfloat, GLfloat, GLfloat);
+typedef void (gl2_APIENTRY *glVertexAttrib4fv_client_proc_t) (void * ctx, GLuint, const GLfloat*);
+typedef void (gl2_APIENTRY *glVertexAttribPointer_client_proc_t) (void * ctx, GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid*);
+typedef void (gl2_APIENTRY *glViewport_client_proc_t) (void * ctx, GLint, GLint, GLsizei, GLsizei);
+typedef void (gl2_APIENTRY *glEGLImageTargetTexture2DOES_client_proc_t) (void * ctx, GLenum, GLeglImageOES);
+typedef void (gl2_APIENTRY *glEGLImageTargetRenderbufferStorageOES_client_proc_t) (void * ctx, GLenum, GLeglImageOES);
+typedef void (gl2_APIENTRY *glGetProgramBinaryOES_client_proc_t) (void * ctx, GLuint, GLsizei, GLsizei*, GLenum*, GLvoid*);
+typedef void (gl2_APIENTRY *glProgramBinaryOES_client_proc_t) (void * ctx, GLuint, GLenum, const GLvoid*, GLint);
+typedef void* (gl2_APIENTRY *glMapBufferOES_client_proc_t) (void * ctx, GLenum, GLenum);
+typedef GLboolean (gl2_APIENTRY *glUnmapBufferOES_client_proc_t) (void * ctx, GLenum);
+typedef void (gl2_APIENTRY *glTexImage3DOES_client_proc_t) (void * ctx, GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid*);
+typedef void (gl2_APIENTRY *glTexSubImage3DOES_client_proc_t) (void * ctx, GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid*);
+typedef void (gl2_APIENTRY *glCopyTexSubImage3DOES_client_proc_t) (void * ctx, GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei);
+typedef void (gl2_APIENTRY *glCompressedTexImage3DOES_client_proc_t) (void * ctx, GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid*);
+typedef void (gl2_APIENTRY *glCompressedTexSubImage3DOES_client_proc_t) (void * ctx, GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid*);
+typedef void (gl2_APIENTRY *glFramebufferTexture3DOES_client_proc_t) (void * ctx, GLenum, GLenum, GLenum, GLuint, GLint, GLint);
+typedef void (gl2_APIENTRY *glBindVertexArrayOES_client_proc_t) (void * ctx, GLuint);
+typedef void (gl2_APIENTRY *glDeleteVertexArraysOES_client_proc_t) (void * ctx, GLsizei, const GLuint*);
+typedef void (gl2_APIENTRY *glGenVertexArraysOES_client_proc_t) (void * ctx, GLsizei, GLuint*);
+typedef GLboolean (gl2_APIENTRY *glIsVertexArrayOES_client_proc_t) (void * ctx, GLuint);
+typedef void (gl2_APIENTRY *glDiscardFramebufferEXT_client_proc_t) (void * ctx, GLenum, GLsizei, const GLenum*);
+typedef void (gl2_APIENTRY *glMultiDrawArraysEXT_client_proc_t) (void * ctx, GLenum, GLint*, GLsizei*, GLsizei);
+typedef void (gl2_APIENTRY *glMultiDrawElementsEXT_client_proc_t) (void * ctx, GLenum, const GLsizei*, GLenum, const GLvoid**, GLsizei);
+typedef void (gl2_APIENTRY *glGetPerfMonitorGroupsAMD_client_proc_t) (void * ctx, GLint*, GLsizei, GLuint*);
+typedef void (gl2_APIENTRY *glGetPerfMonitorCountersAMD_client_proc_t) (void * ctx, GLuint, GLint*, GLint*, GLsizei, GLuint*);
+typedef void (gl2_APIENTRY *glGetPerfMonitorGroupStringAMD_client_proc_t) (void * ctx, GLuint, GLsizei, GLsizei*, GLchar*);
+typedef void (gl2_APIENTRY *glGetPerfMonitorCounterStringAMD_client_proc_t) (void * ctx, GLuint, GLuint, GLsizei, GLsizei*, GLchar*);
+typedef void (gl2_APIENTRY *glGetPerfMonitorCounterInfoAMD_client_proc_t) (void * ctx, GLuint, GLuint, GLenum, GLvoid*);
+typedef void (gl2_APIENTRY *glGenPerfMonitorsAMD_client_proc_t) (void * ctx, GLsizei, GLuint*);
+typedef void (gl2_APIENTRY *glDeletePerfMonitorsAMD_client_proc_t) (void * ctx, GLsizei, GLuint*);
+typedef void (gl2_APIENTRY *glSelectPerfMonitorCountersAMD_client_proc_t) (void * ctx, GLuint, GLboolean, GLuint, GLint, GLuint*);
+typedef void (gl2_APIENTRY *glBeginPerfMonitorAMD_client_proc_t) (void * ctx, GLuint);
+typedef void (gl2_APIENTRY *glEndPerfMonitorAMD_client_proc_t) (void * ctx, GLuint);
+typedef void (gl2_APIENTRY *glGetPerfMonitorCounterDataAMD_client_proc_t) (void * ctx, GLuint, GLenum, GLsizei, GLuint*, GLint*);
+typedef void (gl2_APIENTRY *glRenderbufferStorageMultisampleIMG_client_proc_t) (void * ctx, GLenum, GLsizei, GLenum, GLsizei, GLsizei);
+typedef void (gl2_APIENTRY *glFramebufferTexture2DMultisampleIMG_client_proc_t) (void * ctx, GLenum, GLenum, GLenum, GLuint, GLint, GLsizei);
+typedef void (gl2_APIENTRY *glDeleteFencesNV_client_proc_t) (void * ctx, GLsizei, const GLuint*);
+typedef void (gl2_APIENTRY *glGenFencesNV_client_proc_t) (void * ctx, GLsizei, GLuint*);
+typedef GLboolean (gl2_APIENTRY *glIsFenceNV_client_proc_t) (void * ctx, GLuint);
+typedef GLboolean (gl2_APIENTRY *glTestFenceNV_client_proc_t) (void * ctx, GLuint);
+typedef void (gl2_APIENTRY *glGetFenceivNV_client_proc_t) (void * ctx, GLuint, GLenum, GLint*);
+typedef void (gl2_APIENTRY *glFinishFenceNV_client_proc_t) (void * ctx, GLuint);
+typedef void (gl2_APIENTRY *glSetFenceNV_client_proc_t) (void * ctx, GLuint, GLenum);
+typedef void (gl2_APIENTRY *glCoverageMaskNV_client_proc_t) (void * ctx, GLboolean);
+typedef void (gl2_APIENTRY *glCoverageOperationNV_client_proc_t) (void * ctx, GLenum);
+typedef void (gl2_APIENTRY *glGetDriverControlsQCOM_client_proc_t) (void * ctx, GLint*, GLsizei, GLuint*);
+typedef void (gl2_APIENTRY *glGetDriverControlStringQCOM_client_proc_t) (void * ctx, GLuint, GLsizei, GLsizei*, GLchar*);
+typedef void (gl2_APIENTRY *glEnableDriverControlQCOM_client_proc_t) (void * ctx, GLuint);
+typedef void (gl2_APIENTRY *glDisableDriverControlQCOM_client_proc_t) (void * ctx, GLuint);
+typedef void (gl2_APIENTRY *glExtGetTexturesQCOM_client_proc_t) (void * ctx, GLuint*, GLint, GLint*);
+typedef void (gl2_APIENTRY *glExtGetBuffersQCOM_client_proc_t) (void * ctx, GLuint*, GLint, GLint*);
+typedef void (gl2_APIENTRY *glExtGetRenderbuffersQCOM_client_proc_t) (void * ctx, GLuint*, GLint, GLint*);
+typedef void (gl2_APIENTRY *glExtGetFramebuffersQCOM_client_proc_t) (void * ctx, GLuint*, GLint, GLint*);
+typedef void (gl2_APIENTRY *glExtGetTexLevelParameterivQCOM_client_proc_t) (void * ctx, GLuint, GLenum, GLint, GLenum, GLint*);
+typedef void (gl2_APIENTRY *glExtTexObjectStateOverrideiQCOM_client_proc_t) (void * ctx, GLenum, GLenum, GLint);
+typedef void (gl2_APIENTRY *glExtGetTexSubImageQCOM_client_proc_t) (void * ctx, GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, GLvoid*);
+typedef void (gl2_APIENTRY *glExtGetBufferPointervQCOM_client_proc_t) (void * ctx, GLenum, GLvoidptr*);
+typedef void (gl2_APIENTRY *glExtGetShadersQCOM_client_proc_t) (void * ctx, GLuint*, GLint, GLint*);
+typedef void (gl2_APIENTRY *glExtGetProgramsQCOM_client_proc_t) (void * ctx, GLuint*, GLint, GLint*);
+typedef GLboolean (gl2_APIENTRY *glExtIsProgramBinaryQCOM_client_proc_t) (void * ctx, GLuint);
+typedef void (gl2_APIENTRY *glExtGetProgramBinarySourceQCOM_client_proc_t) (void * ctx, GLuint, GLenum, GLchar*, GLint*);
+typedef void (gl2_APIENTRY *glStartTilingQCOM_client_proc_t) (void * ctx, GLuint, GLuint, GLuint, GLuint, GLbitfield);
+typedef void (gl2_APIENTRY *glEndTilingQCOM_client_proc_t) (void * ctx, GLbitfield);
+typedef void (gl2_APIENTRY *glVertexAttribPointerData_client_proc_t) (void * ctx, GLuint, GLint, GLenum, GLboolean, GLsizei, void*, GLuint);
+typedef void (gl2_APIENTRY *glVertexAttribPointerOffset_client_proc_t) (void * ctx, GLuint, GLint, GLenum, GLboolean, GLsizei, GLuint);
+typedef void (gl2_APIENTRY *glDrawElementsOffset_client_proc_t) (void * ctx, GLenum, GLsizei, GLenum, GLuint);
+typedef void (gl2_APIENTRY *glDrawElementsData_client_proc_t) (void * ctx, GLenum, GLsizei, GLenum, void*, GLuint);
+typedef void (gl2_APIENTRY *glGetCompressedTextureFormats_client_proc_t) (void * ctx, int, GLint*);
+typedef void (gl2_APIENTRY *glShaderString_client_proc_t) (void * ctx, GLuint, const GLchar*, GLsizei);
+typedef int (gl2_APIENTRY *glFinishRoundTrip_client_proc_t) (void * ctx);
+
+
+#endif
diff --git a/opengl/system/GLESv2_enc/gl2_enc.cpp b/opengl/system/GLESv2_enc/gl2_enc.cpp
new file mode 100644
index 0000000..46684e9
--- /dev/null
+++ b/opengl/system/GLESv2_enc/gl2_enc.cpp
@@ -0,0 +1,3130 @@
+// Generated Code - DO NOT EDIT !!
+// generated by 'emugen'
+
+
+#include <string.h>
+#include "gl2_opcodes.h"
+
+#include "gl2_enc.h"
+
+
+#include <stdio.h>
+static void enc_unsupported()
+{
+	ALOGE("Function is unsupported\n");
+}
+
+void glActiveTexture_enc(void *self , GLenum texture)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glActiveTexture;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &texture, 4); ptr += 4;
+}
+
+void glAttachShader_enc(void *self , GLuint program, GLuint shader)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glAttachShader;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &program, 4); ptr += 4;
+		memcpy(ptr, &shader, 4); ptr += 4;
+}
+
+void glBindAttribLocation_enc(void *self , GLuint program, GLuint index, const GLchar* name)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_name =  (strlen(name) + 1);
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_name + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glBindAttribLocation;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &program, 4); ptr += 4;
+		memcpy(ptr, &index, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_name; ptr += 4;
+	memcpy(ptr, name, __size_name);ptr += __size_name;
+}
+
+void glBindBuffer_enc(void *self , GLenum target, GLuint buffer)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glBindBuffer;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &buffer, 4); ptr += 4;
+}
+
+void glBindFramebuffer_enc(void *self , GLenum target, GLuint framebuffer)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glBindFramebuffer;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &framebuffer, 4); ptr += 4;
+}
+
+void glBindRenderbuffer_enc(void *self , GLenum target, GLuint renderbuffer)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glBindRenderbuffer;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &renderbuffer, 4); ptr += 4;
+}
+
+void glBindTexture_enc(void *self , GLenum target, GLuint texture)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glBindTexture;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &texture, 4); ptr += 4;
+}
+
+void glBlendColor_enc(void *self , GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glBlendColor;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &red, 4); ptr += 4;
+		memcpy(ptr, &green, 4); ptr += 4;
+		memcpy(ptr, &blue, 4); ptr += 4;
+		memcpy(ptr, &alpha, 4); ptr += 4;
+}
+
+void glBlendEquation_enc(void *self , GLenum mode)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glBlendEquation;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &mode, 4); ptr += 4;
+}
+
+void glBlendEquationSeparate_enc(void *self , GLenum modeRGB, GLenum modeAlpha)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glBlendEquationSeparate;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &modeRGB, 4); ptr += 4;
+		memcpy(ptr, &modeAlpha, 4); ptr += 4;
+}
+
+void glBlendFunc_enc(void *self , GLenum sfactor, GLenum dfactor)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glBlendFunc;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &sfactor, 4); ptr += 4;
+		memcpy(ptr, &dfactor, 4); ptr += 4;
+}
+
+void glBlendFuncSeparate_enc(void *self , GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glBlendFuncSeparate;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &srcRGB, 4); ptr += 4;
+		memcpy(ptr, &dstRGB, 4); ptr += 4;
+		memcpy(ptr, &srcAlpha, 4); ptr += 4;
+		memcpy(ptr, &dstAlpha, 4); ptr += 4;
+}
+
+void glBufferData_enc(void *self , GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_data = ((data != NULL) ?  size : 0);
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_data + 4 + 1*4;
+	ptr = stream->alloc(8 + 4 + 4);
+	int tmp = OP_glBufferData;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &size, 4); ptr += 4;
+	stream->flush();
+	stream->writeFully(&__size_data,4);
+	if (data != NULL) stream->writeFully(data, __size_data);
+	ptr = stream->alloc(4);
+		memcpy(ptr, &usage, 4); ptr += 4;
+}
+
+void glBufferSubData_enc(void *self , GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_data =  size;
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + __size_data + 1*4;
+	ptr = stream->alloc(8 + 4 + 4 + 4);
+	int tmp = OP_glBufferSubData;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &offset, 4); ptr += 4;
+		memcpy(ptr, &size, 4); ptr += 4;
+	stream->flush();
+	stream->writeFully(&__size_data,4);
+	stream->writeFully(data, __size_data);
+}
+
+GLenum glCheckFramebufferStatus_enc(void *self , GLenum target)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glCheckFramebufferStatus;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+
+	GLenum retval;
+	stream->readback(&retval, 4);
+	return retval;
+}
+
+void glClear_enc(void *self , GLbitfield mask)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glClear;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &mask, 4); ptr += 4;
+}
+
+void glClearColor_enc(void *self , GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glClearColor;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &red, 4); ptr += 4;
+		memcpy(ptr, &green, 4); ptr += 4;
+		memcpy(ptr, &blue, 4); ptr += 4;
+		memcpy(ptr, &alpha, 4); ptr += 4;
+}
+
+void glClearDepthf_enc(void *self , GLclampf depth)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glClearDepthf;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &depth, 4); ptr += 4;
+}
+
+void glClearStencil_enc(void *self , GLint s)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glClearStencil;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &s, 4); ptr += 4;
+}
+
+void glColorMask_enc(void *self , GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 1 + 1 + 1 + 1;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glColorMask;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &red, 1); ptr += 1;
+		memcpy(ptr, &green, 1); ptr += 1;
+		memcpy(ptr, &blue, 1); ptr += 1;
+		memcpy(ptr, &alpha, 1); ptr += 1;
+}
+
+void glCompileShader_enc(void *self , GLuint shader)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glCompileShader;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &shader, 4); ptr += 4;
+}
+
+void glCompressedTexImage2D_enc(void *self , GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_data = ((data != NULL) ?  imageSize : 0);
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + __size_data + 1*4;
+	ptr = stream->alloc(8 + 4 + 4 + 4 + 4 + 4 + 4 + 4);
+	int tmp = OP_glCompressedTexImage2D;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &level, 4); ptr += 4;
+		memcpy(ptr, &internalformat, 4); ptr += 4;
+		memcpy(ptr, &width, 4); ptr += 4;
+		memcpy(ptr, &height, 4); ptr += 4;
+		memcpy(ptr, &border, 4); ptr += 4;
+		memcpy(ptr, &imageSize, 4); ptr += 4;
+	stream->flush();
+	stream->writeFully(&__size_data,4);
+	if (data != NULL) stream->writeFully(data, __size_data);
+}
+
+void glCompressedTexSubImage2D_enc(void *self , GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_data =  imageSize;
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + __size_data + 1*4;
+	ptr = stream->alloc(8 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4);
+	int tmp = OP_glCompressedTexSubImage2D;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &level, 4); ptr += 4;
+		memcpy(ptr, &xoffset, 4); ptr += 4;
+		memcpy(ptr, &yoffset, 4); ptr += 4;
+		memcpy(ptr, &width, 4); ptr += 4;
+		memcpy(ptr, &height, 4); ptr += 4;
+		memcpy(ptr, &format, 4); ptr += 4;
+		memcpy(ptr, &imageSize, 4); ptr += 4;
+	stream->flush();
+	stream->writeFully(&__size_data,4);
+	stream->writeFully(data, __size_data);
+}
+
+void glCopyTexImage2D_enc(void *self , GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glCopyTexImage2D;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &level, 4); ptr += 4;
+		memcpy(ptr, &internalformat, 4); ptr += 4;
+		memcpy(ptr, &x, 4); ptr += 4;
+		memcpy(ptr, &y, 4); ptr += 4;
+		memcpy(ptr, &width, 4); ptr += 4;
+		memcpy(ptr, &height, 4); ptr += 4;
+		memcpy(ptr, &border, 4); ptr += 4;
+}
+
+void glCopyTexSubImage2D_enc(void *self , GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glCopyTexSubImage2D;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &level, 4); ptr += 4;
+		memcpy(ptr, &xoffset, 4); ptr += 4;
+		memcpy(ptr, &yoffset, 4); ptr += 4;
+		memcpy(ptr, &x, 4); ptr += 4;
+		memcpy(ptr, &y, 4); ptr += 4;
+		memcpy(ptr, &width, 4); ptr += 4;
+		memcpy(ptr, &height, 4); ptr += 4;
+}
+
+GLuint glCreateProgram_enc(void *self )
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 0;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glCreateProgram;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+
+	GLuint retval;
+	stream->readback(&retval, 4);
+	return retval;
+}
+
+GLuint glCreateShader_enc(void *self , GLenum type)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glCreateShader;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &type, 4); ptr += 4;
+
+	GLuint retval;
+	stream->readback(&retval, 4);
+	return retval;
+}
+
+void glCullFace_enc(void *self , GLenum mode)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glCullFace;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &mode, 4); ptr += 4;
+}
+
+void glDeleteBuffers_enc(void *self , GLsizei n, const GLuint* buffers)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_buffers =  (n * sizeof(GLuint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_buffers + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glDeleteBuffers;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &n, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_buffers; ptr += 4;
+	memcpy(ptr, buffers, __size_buffers);ptr += __size_buffers;
+}
+
+void glDeleteFramebuffers_enc(void *self , GLsizei n, const GLuint* framebuffers)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_framebuffers =  (n * sizeof(GLuint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_framebuffers + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glDeleteFramebuffers;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &n, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_framebuffers; ptr += 4;
+	memcpy(ptr, framebuffers, __size_framebuffers);ptr += __size_framebuffers;
+}
+
+void glDeleteProgram_enc(void *self , GLuint program)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glDeleteProgram;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &program, 4); ptr += 4;
+}
+
+void glDeleteRenderbuffers_enc(void *self , GLsizei n, const GLuint* renderbuffers)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_renderbuffers =  (n * sizeof(GLuint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_renderbuffers + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glDeleteRenderbuffers;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &n, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_renderbuffers; ptr += 4;
+	memcpy(ptr, renderbuffers, __size_renderbuffers);ptr += __size_renderbuffers;
+}
+
+void glDeleteShader_enc(void *self , GLuint shader)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glDeleteShader;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &shader, 4); ptr += 4;
+}
+
+void glDeleteTextures_enc(void *self , GLsizei n, const GLuint* textures)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_textures =  (n * sizeof(GLuint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_textures + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glDeleteTextures;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &n, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_textures; ptr += 4;
+	memcpy(ptr, textures, __size_textures);ptr += __size_textures;
+}
+
+void glDepthFunc_enc(void *self , GLenum func)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glDepthFunc;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &func, 4); ptr += 4;
+}
+
+void glDepthMask_enc(void *self , GLboolean flag)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 1;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glDepthMask;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &flag, 1); ptr += 1;
+}
+
+void glDepthRangef_enc(void *self , GLclampf zNear, GLclampf zFar)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glDepthRangef;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &zNear, 4); ptr += 4;
+		memcpy(ptr, &zFar, 4); ptr += 4;
+}
+
+void glDetachShader_enc(void *self , GLuint program, GLuint shader)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glDetachShader;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &program, 4); ptr += 4;
+		memcpy(ptr, &shader, 4); ptr += 4;
+}
+
+void glDisable_enc(void *self , GLenum cap)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glDisable;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &cap, 4); ptr += 4;
+}
+
+void glDisableVertexAttribArray_enc(void *self , GLuint index)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glDisableVertexAttribArray;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &index, 4); ptr += 4;
+}
+
+void glDrawArrays_enc(void *self , GLenum mode, GLint first, GLsizei count)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glDrawArrays;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &mode, 4); ptr += 4;
+		memcpy(ptr, &first, 4); ptr += 4;
+		memcpy(ptr, &count, 4); ptr += 4;
+}
+
+void glEnable_enc(void *self , GLenum cap)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glEnable;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &cap, 4); ptr += 4;
+}
+
+void glEnableVertexAttribArray_enc(void *self , GLuint index)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glEnableVertexAttribArray;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &index, 4); ptr += 4;
+}
+
+void glFinish_enc(void *self )
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 0;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glFinish;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+}
+
+void glFlush_enc(void *self )
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 0;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glFlush;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+}
+
+void glFramebufferRenderbuffer_enc(void *self , GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glFramebufferRenderbuffer;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &attachment, 4); ptr += 4;
+		memcpy(ptr, &renderbuffertarget, 4); ptr += 4;
+		memcpy(ptr, &renderbuffer, 4); ptr += 4;
+}
+
+void glFramebufferTexture2D_enc(void *self , GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glFramebufferTexture2D;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &attachment, 4); ptr += 4;
+		memcpy(ptr, &textarget, 4); ptr += 4;
+		memcpy(ptr, &texture, 4); ptr += 4;
+		memcpy(ptr, &level, 4); ptr += 4;
+}
+
+void glFrontFace_enc(void *self , GLenum mode)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glFrontFace;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &mode, 4); ptr += 4;
+}
+
+void glGenBuffers_enc(void *self , GLsizei n, GLuint* buffers)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_buffers =  (n * sizeof(GLuint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_buffers + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGenBuffers;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &n, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_buffers; ptr += 4;
+	stream->readback(buffers, __size_buffers);
+}
+
+void glGenerateMipmap_enc(void *self , GLenum target)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGenerateMipmap;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+}
+
+void glGenFramebuffers_enc(void *self , GLsizei n, GLuint* framebuffers)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_framebuffers =  (n * sizeof(GLuint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_framebuffers + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGenFramebuffers;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &n, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_framebuffers; ptr += 4;
+	stream->readback(framebuffers, __size_framebuffers);
+}
+
+void glGenRenderbuffers_enc(void *self , GLsizei n, GLuint* renderbuffers)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_renderbuffers =  (n * sizeof(GLuint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_renderbuffers + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGenRenderbuffers;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &n, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_renderbuffers; ptr += 4;
+	stream->readback(renderbuffers, __size_renderbuffers);
+}
+
+void glGenTextures_enc(void *self , GLsizei n, GLuint* textures)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_textures =  (n * sizeof(GLuint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_textures + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGenTextures;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &n, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_textures; ptr += 4;
+	stream->readback(textures, __size_textures);
+}
+
+void glGetActiveAttrib_enc(void *self , GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_length = ((length != NULL) ?  (sizeof(GLsizei)) : 0);
+	const unsigned int __size_size =  (sizeof(GLint));
+	const unsigned int __size_type =  (sizeof(GLenum));
+	const unsigned int __size_name = ((name != NULL) ?  bufsize : 0);
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + __size_length + __size_size + __size_type + __size_name + 4*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetActiveAttrib;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &program, 4); ptr += 4;
+		memcpy(ptr, &index, 4); ptr += 4;
+		memcpy(ptr, &bufsize, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_length; ptr += 4;
+	*(unsigned int *)(ptr) = __size_size; ptr += 4;
+	*(unsigned int *)(ptr) = __size_type; ptr += 4;
+	*(unsigned int *)(ptr) = __size_name; ptr += 4;
+	if (length != NULL) stream->readback(length, __size_length);
+	stream->readback(size, __size_size);
+	stream->readback(type, __size_type);
+	if (name != NULL) stream->readback(name, __size_name);
+}
+
+void glGetActiveUniform_enc(void *self , GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_length = ((length != NULL) ?  (sizeof(GLsizei)) : 0);
+	const unsigned int __size_size =  (sizeof(GLint));
+	const unsigned int __size_type =  (sizeof(GLenum));
+	const unsigned int __size_name = ((name != NULL) ?  bufsize : 0);
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + __size_length + __size_size + __size_type + __size_name + 4*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetActiveUniform;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &program, 4); ptr += 4;
+		memcpy(ptr, &index, 4); ptr += 4;
+		memcpy(ptr, &bufsize, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_length; ptr += 4;
+	*(unsigned int *)(ptr) = __size_size; ptr += 4;
+	*(unsigned int *)(ptr) = __size_type; ptr += 4;
+	*(unsigned int *)(ptr) = __size_name; ptr += 4;
+	if (length != NULL) stream->readback(length, __size_length);
+	stream->readback(size, __size_size);
+	stream->readback(type, __size_type);
+	if (name != NULL) stream->readback(name, __size_name);
+}
+
+void glGetAttachedShaders_enc(void *self , GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_count = ((count != NULL) ?  (sizeof(GLsizei)) : 0);
+	const unsigned int __size_shaders =  (maxcount*sizeof(GLuint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_count + __size_shaders + 2*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetAttachedShaders;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &program, 4); ptr += 4;
+		memcpy(ptr, &maxcount, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_count; ptr += 4;
+	*(unsigned int *)(ptr) = __size_shaders; ptr += 4;
+	if (count != NULL) stream->readback(count, __size_count);
+	stream->readback(shaders, __size_shaders);
+}
+
+int glGetAttribLocation_enc(void *self , GLuint program, const GLchar* name)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_name =  (strlen(name) + 1);
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_name + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetAttribLocation;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &program, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_name; ptr += 4;
+	memcpy(ptr, name, __size_name);ptr += __size_name;
+
+	int retval;
+	stream->readback(&retval, 4);
+	return retval;
+}
+
+void glGetBooleanv_enc(void *self , GLenum pname, GLboolean* params)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLboolean));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetBooleanv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	stream->readback(params, __size_params);
+}
+
+void glGetBufferParameteriv_enc(void *self , GLenum target, GLenum pname, GLint* params)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (sizeof(GLint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetBufferParameteriv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	stream->readback(params, __size_params);
+}
+
+GLenum glGetError_enc(void *self )
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 0;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetError;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+
+	GLenum retval;
+	stream->readback(&retval, 4);
+	return retval;
+}
+
+void glGetFloatv_enc(void *self , GLenum pname, GLfloat* params)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLfloat));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetFloatv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	stream->readback(params, __size_params);
+}
+
+void glGetFramebufferAttachmentParameteriv_enc(void *self , GLenum target, GLenum attachment, GLenum pname, GLint* params)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (sizeof(GLint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetFramebufferAttachmentParameteriv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &attachment, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	stream->readback(params, __size_params);
+}
+
+void glGetIntegerv_enc(void *self , GLenum pname, GLint* params)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetIntegerv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	stream->readback(params, __size_params);
+}
+
+void glGetProgramiv_enc(void *self , GLuint program, GLenum pname, GLint* params)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  sizeof(GLint);
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetProgramiv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &program, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	stream->readback(params, __size_params);
+}
+
+void glGetProgramInfoLog_enc(void *self , GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_length =  sizeof(GLsizei);
+	const unsigned int __size_infolog =  bufsize;
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_length + __size_infolog + 2*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetProgramInfoLog;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &program, 4); ptr += 4;
+		memcpy(ptr, &bufsize, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_length; ptr += 4;
+	*(unsigned int *)(ptr) = __size_infolog; ptr += 4;
+	stream->readback(length, __size_length);
+	stream->readback(infolog, __size_infolog);
+}
+
+void glGetRenderbufferParameteriv_enc(void *self , GLenum target, GLenum pname, GLint* params)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  sizeof(GLint);
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetRenderbufferParameteriv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	stream->readback(params, __size_params);
+}
+
+void glGetShaderiv_enc(void *self , GLuint shader, GLenum pname, GLint* params)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  sizeof(GLint);
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetShaderiv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &shader, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	stream->readback(params, __size_params);
+}
+
+void glGetShaderInfoLog_enc(void *self , GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_length = ((length != NULL) ?  (sizeof(GLsizei)) : 0);
+	const unsigned int __size_infolog =  bufsize;
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_length + __size_infolog + 2*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetShaderInfoLog;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &shader, 4); ptr += 4;
+		memcpy(ptr, &bufsize, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_length; ptr += 4;
+	*(unsigned int *)(ptr) = __size_infolog; ptr += 4;
+	if (length != NULL) stream->readback(length, __size_length);
+	stream->readback(infolog, __size_infolog);
+}
+
+void glGetShaderPrecisionFormat_enc(void *self , GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_range =  (2 * sizeof(GLint));
+	const unsigned int __size_precision =  (sizeof(GLint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_range + __size_precision + 2*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetShaderPrecisionFormat;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &shadertype, 4); ptr += 4;
+		memcpy(ptr, &precisiontype, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_range; ptr += 4;
+	*(unsigned int *)(ptr) = __size_precision; ptr += 4;
+	stream->readback(range, __size_range);
+	stream->readback(precision, __size_precision);
+}
+
+void glGetShaderSource_enc(void *self , GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_length = ((length != NULL) ?  (sizeof(GLsizei)) : 0);
+	const unsigned int __size_source =  bufsize;
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_length + __size_source + 2*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetShaderSource;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &shader, 4); ptr += 4;
+		memcpy(ptr, &bufsize, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_length; ptr += 4;
+	*(unsigned int *)(ptr) = __size_source; ptr += 4;
+	if (length != NULL) stream->readback(length, __size_length);
+	stream->readback(source, __size_source);
+}
+
+void glGetTexParameterfv_enc(void *self , GLenum target, GLenum pname, GLfloat* params)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLfloat));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetTexParameterfv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	stream->readback(params, __size_params);
+}
+
+void glGetTexParameteriv_enc(void *self , GLenum target, GLenum pname, GLint* params)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetTexParameteriv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	stream->readback(params, __size_params);
+}
+
+void glGetUniformfv_enc(void *self , GLuint program, GLint location, GLfloat* params)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  glSizeof(uniformType(self, program, location));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetUniformfv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &program, 4); ptr += 4;
+		memcpy(ptr, &location, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	stream->readback(params, __size_params);
+}
+
+void glGetUniformiv_enc(void *self , GLuint program, GLint location, GLint* params)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  glSizeof(uniformType(self, program, location));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetUniformiv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &program, 4); ptr += 4;
+		memcpy(ptr, &location, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	stream->readback(params, __size_params);
+}
+
+int glGetUniformLocation_enc(void *self , GLuint program, const GLchar* name)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_name =  (strlen(name) + 1);
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_name + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetUniformLocation;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &program, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_name; ptr += 4;
+	memcpy(ptr, name, __size_name);ptr += __size_name;
+
+	int retval;
+	stream->readback(&retval, 4);
+	return retval;
+}
+
+void glGetVertexAttribfv_enc(void *self , GLuint index, GLenum pname, GLfloat* params)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLfloat));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetVertexAttribfv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &index, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	stream->readback(params, __size_params);
+}
+
+void glGetVertexAttribiv_enc(void *self , GLuint index, GLenum pname, GLint* params)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetVertexAttribiv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &index, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	stream->readback(params, __size_params);
+}
+
+void glHint_enc(void *self , GLenum target, GLenum mode)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glHint;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &mode, 4); ptr += 4;
+}
+
+GLboolean glIsBuffer_enc(void *self , GLuint buffer)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glIsBuffer;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &buffer, 4); ptr += 4;
+
+	GLboolean retval;
+	stream->readback(&retval, 1);
+	return retval;
+}
+
+GLboolean glIsEnabled_enc(void *self , GLenum cap)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glIsEnabled;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &cap, 4); ptr += 4;
+
+	GLboolean retval;
+	stream->readback(&retval, 1);
+	return retval;
+}
+
+GLboolean glIsFramebuffer_enc(void *self , GLuint framebuffer)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glIsFramebuffer;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &framebuffer, 4); ptr += 4;
+
+	GLboolean retval;
+	stream->readback(&retval, 1);
+	return retval;
+}
+
+GLboolean glIsProgram_enc(void *self , GLuint program)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glIsProgram;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &program, 4); ptr += 4;
+
+	GLboolean retval;
+	stream->readback(&retval, 1);
+	return retval;
+}
+
+GLboolean glIsRenderbuffer_enc(void *self , GLuint renderbuffer)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glIsRenderbuffer;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &renderbuffer, 4); ptr += 4;
+
+	GLboolean retval;
+	stream->readback(&retval, 1);
+	return retval;
+}
+
+GLboolean glIsShader_enc(void *self , GLuint shader)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glIsShader;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &shader, 4); ptr += 4;
+
+	GLboolean retval;
+	stream->readback(&retval, 1);
+	return retval;
+}
+
+GLboolean glIsTexture_enc(void *self , GLuint texture)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glIsTexture;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &texture, 4); ptr += 4;
+
+	GLboolean retval;
+	stream->readback(&retval, 1);
+	return retval;
+}
+
+void glLineWidth_enc(void *self , GLfloat width)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glLineWidth;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &width, 4); ptr += 4;
+}
+
+void glLinkProgram_enc(void *self , GLuint program)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glLinkProgram;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &program, 4); ptr += 4;
+}
+
+void glPixelStorei_enc(void *self , GLenum pname, GLint param)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glPixelStorei;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &pname, 4); ptr += 4;
+		memcpy(ptr, &param, 4); ptr += 4;
+}
+
+void glPolygonOffset_enc(void *self , GLfloat factor, GLfloat units)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glPolygonOffset;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &factor, 4); ptr += 4;
+		memcpy(ptr, &units, 4); ptr += 4;
+}
+
+void glReadPixels_enc(void *self , GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_pixels =  pixelDataSize(self, width, height, format, type, 1);
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4 + 4 + __size_pixels + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glReadPixels;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &x, 4); ptr += 4;
+		memcpy(ptr, &y, 4); ptr += 4;
+		memcpy(ptr, &width, 4); ptr += 4;
+		memcpy(ptr, &height, 4); ptr += 4;
+		memcpy(ptr, &format, 4); ptr += 4;
+		memcpy(ptr, &type, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_pixels; ptr += 4;
+	stream->readback(pixels, __size_pixels);
+}
+
+void glReleaseShaderCompiler_enc(void *self )
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 0;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glReleaseShaderCompiler;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+}
+
+void glRenderbufferStorage_enc(void *self , GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glRenderbufferStorage;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &internalformat, 4); ptr += 4;
+		memcpy(ptr, &width, 4); ptr += 4;
+		memcpy(ptr, &height, 4); ptr += 4;
+}
+
+void glSampleCoverage_enc(void *self , GLclampf value, GLboolean invert)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 1;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glSampleCoverage;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &value, 4); ptr += 4;
+		memcpy(ptr, &invert, 1); ptr += 1;
+}
+
+void glScissor_enc(void *self , GLint x, GLint y, GLsizei width, GLsizei height)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glScissor;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &x, 4); ptr += 4;
+		memcpy(ptr, &y, 4); ptr += 4;
+		memcpy(ptr, &width, 4); ptr += 4;
+		memcpy(ptr, &height, 4); ptr += 4;
+}
+
+void glStencilFunc_enc(void *self , GLenum func, GLint ref, GLuint mask)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glStencilFunc;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &func, 4); ptr += 4;
+		memcpy(ptr, &ref, 4); ptr += 4;
+		memcpy(ptr, &mask, 4); ptr += 4;
+}
+
+void glStencilFuncSeparate_enc(void *self , GLenum face, GLenum func, GLint ref, GLuint mask)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glStencilFuncSeparate;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &face, 4); ptr += 4;
+		memcpy(ptr, &func, 4); ptr += 4;
+		memcpy(ptr, &ref, 4); ptr += 4;
+		memcpy(ptr, &mask, 4); ptr += 4;
+}
+
+void glStencilMask_enc(void *self , GLuint mask)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glStencilMask;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &mask, 4); ptr += 4;
+}
+
+void glStencilMaskSeparate_enc(void *self , GLenum face, GLuint mask)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glStencilMaskSeparate;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &face, 4); ptr += 4;
+		memcpy(ptr, &mask, 4); ptr += 4;
+}
+
+void glStencilOp_enc(void *self , GLenum fail, GLenum zfail, GLenum zpass)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glStencilOp;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &fail, 4); ptr += 4;
+		memcpy(ptr, &zfail, 4); ptr += 4;
+		memcpy(ptr, &zpass, 4); ptr += 4;
+}
+
+void glStencilOpSeparate_enc(void *self , GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glStencilOpSeparate;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &face, 4); ptr += 4;
+		memcpy(ptr, &fail, 4); ptr += 4;
+		memcpy(ptr, &zfail, 4); ptr += 4;
+		memcpy(ptr, &zpass, 4); ptr += 4;
+}
+
+void glTexImage2D_enc(void *self , GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_pixels = ((pixels != NULL) ?  pixelDataSize(self, width, height, format, type, 0) : 0);
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + __size_pixels + 1*4;
+	ptr = stream->alloc(8 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4);
+	int tmp = OP_glTexImage2D;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &level, 4); ptr += 4;
+		memcpy(ptr, &internalformat, 4); ptr += 4;
+		memcpy(ptr, &width, 4); ptr += 4;
+		memcpy(ptr, &height, 4); ptr += 4;
+		memcpy(ptr, &border, 4); ptr += 4;
+		memcpy(ptr, &format, 4); ptr += 4;
+		memcpy(ptr, &type, 4); ptr += 4;
+	stream->flush();
+	stream->writeFully(&__size_pixels,4);
+	if (pixels != NULL) stream->writeFully(pixels, __size_pixels);
+}
+
+void glTexParameterf_enc(void *self , GLenum target, GLenum pname, GLfloat param)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glTexParameterf;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+		memcpy(ptr, &param, 4); ptr += 4;
+}
+
+void glTexParameterfv_enc(void *self , GLenum target, GLenum pname, const GLfloat* params)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLfloat));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glTexParameterfv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	memcpy(ptr, params, __size_params);ptr += __size_params;
+}
+
+void glTexParameteri_enc(void *self , GLenum target, GLenum pname, GLint param)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glTexParameteri;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+		memcpy(ptr, &param, 4); ptr += 4;
+}
+
+void glTexParameteriv_enc(void *self , GLenum target, GLenum pname, const GLint* params)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_params =  (glUtilsParamSize(pname) * sizeof(GLint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_params + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glTexParameteriv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &pname, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_params; ptr += 4;
+	memcpy(ptr, params, __size_params);ptr += __size_params;
+}
+
+void glTexSubImage2D_enc(void *self , GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_pixels =  pixelDataSize(self, width, height, format, type, 0);
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + __size_pixels + 1*4;
+	ptr = stream->alloc(8 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4);
+	int tmp = OP_glTexSubImage2D;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &level, 4); ptr += 4;
+		memcpy(ptr, &xoffset, 4); ptr += 4;
+		memcpy(ptr, &yoffset, 4); ptr += 4;
+		memcpy(ptr, &width, 4); ptr += 4;
+		memcpy(ptr, &height, 4); ptr += 4;
+		memcpy(ptr, &format, 4); ptr += 4;
+		memcpy(ptr, &type, 4); ptr += 4;
+	stream->flush();
+	stream->writeFully(&__size_pixels,4);
+	stream->writeFully(pixels, __size_pixels);
+}
+
+void glUniform1f_enc(void *self , GLint location, GLfloat x)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glUniform1f;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &location, 4); ptr += 4;
+		memcpy(ptr, &x, 4); ptr += 4;
+}
+
+void glUniform1fv_enc(void *self , GLint location, GLsizei count, const GLfloat* v)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_v =  (count * sizeof(GLfloat));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_v + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glUniform1fv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &location, 4); ptr += 4;
+		memcpy(ptr, &count, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_v; ptr += 4;
+	memcpy(ptr, v, __size_v);ptr += __size_v;
+}
+
+void glUniform1i_enc(void *self , GLint location, GLint x)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glUniform1i;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &location, 4); ptr += 4;
+		memcpy(ptr, &x, 4); ptr += 4;
+}
+
+void glUniform1iv_enc(void *self , GLint location, GLsizei count, const GLint* v)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_v =  (count * sizeof(GLint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_v + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glUniform1iv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &location, 4); ptr += 4;
+		memcpy(ptr, &count, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_v; ptr += 4;
+	memcpy(ptr, v, __size_v);ptr += __size_v;
+}
+
+void glUniform2f_enc(void *self , GLint location, GLfloat x, GLfloat y)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glUniform2f;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &location, 4); ptr += 4;
+		memcpy(ptr, &x, 4); ptr += 4;
+		memcpy(ptr, &y, 4); ptr += 4;
+}
+
+void glUniform2fv_enc(void *self , GLint location, GLsizei count, const GLfloat* v)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_v =  (count * 2 * sizeof(GLfloat));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_v + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glUniform2fv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &location, 4); ptr += 4;
+		memcpy(ptr, &count, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_v; ptr += 4;
+	memcpy(ptr, v, __size_v);ptr += __size_v;
+}
+
+void glUniform2i_enc(void *self , GLint location, GLint x, GLint y)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glUniform2i;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &location, 4); ptr += 4;
+		memcpy(ptr, &x, 4); ptr += 4;
+		memcpy(ptr, &y, 4); ptr += 4;
+}
+
+void glUniform2iv_enc(void *self , GLint location, GLsizei count, const GLint* v)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_v =  (count * 2 * sizeof(GLint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_v + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glUniform2iv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &location, 4); ptr += 4;
+		memcpy(ptr, &count, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_v; ptr += 4;
+	memcpy(ptr, v, __size_v);ptr += __size_v;
+}
+
+void glUniform3f_enc(void *self , GLint location, GLfloat x, GLfloat y, GLfloat z)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glUniform3f;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &location, 4); ptr += 4;
+		memcpy(ptr, &x, 4); ptr += 4;
+		memcpy(ptr, &y, 4); ptr += 4;
+		memcpy(ptr, &z, 4); ptr += 4;
+}
+
+void glUniform3fv_enc(void *self , GLint location, GLsizei count, const GLfloat* v)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_v =  (count * 3 * sizeof(GLfloat));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_v + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glUniform3fv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &location, 4); ptr += 4;
+		memcpy(ptr, &count, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_v; ptr += 4;
+	memcpy(ptr, v, __size_v);ptr += __size_v;
+}
+
+void glUniform3i_enc(void *self , GLint location, GLint x, GLint y, GLint z)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glUniform3i;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &location, 4); ptr += 4;
+		memcpy(ptr, &x, 4); ptr += 4;
+		memcpy(ptr, &y, 4); ptr += 4;
+		memcpy(ptr, &z, 4); ptr += 4;
+}
+
+void glUniform3iv_enc(void *self , GLint location, GLsizei count, const GLint* v)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_v =  (3 * count * sizeof(GLint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_v + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glUniform3iv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &location, 4); ptr += 4;
+		memcpy(ptr, &count, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_v; ptr += 4;
+	memcpy(ptr, v, __size_v);ptr += __size_v;
+}
+
+void glUniform4f_enc(void *self , GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glUniform4f;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &location, 4); ptr += 4;
+		memcpy(ptr, &x, 4); ptr += 4;
+		memcpy(ptr, &y, 4); ptr += 4;
+		memcpy(ptr, &z, 4); ptr += 4;
+		memcpy(ptr, &w, 4); ptr += 4;
+}
+
+void glUniform4fv_enc(void *self , GLint location, GLsizei count, const GLfloat* v)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_v =  (4 * count * sizeof(GLfloat));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_v + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glUniform4fv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &location, 4); ptr += 4;
+		memcpy(ptr, &count, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_v; ptr += 4;
+	memcpy(ptr, v, __size_v);ptr += __size_v;
+}
+
+void glUniform4i_enc(void *self , GLint location, GLint x, GLint y, GLint z, GLint w)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glUniform4i;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &location, 4); ptr += 4;
+		memcpy(ptr, &x, 4); ptr += 4;
+		memcpy(ptr, &y, 4); ptr += 4;
+		memcpy(ptr, &z, 4); ptr += 4;
+		memcpy(ptr, &w, 4); ptr += 4;
+}
+
+void glUniform4iv_enc(void *self , GLint location, GLsizei count, const GLint* v)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_v =  (4 * count * sizeof(GLint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_v + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glUniform4iv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &location, 4); ptr += 4;
+		memcpy(ptr, &count, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_v; ptr += 4;
+	memcpy(ptr, v, __size_v);ptr += __size_v;
+}
+
+void glUniformMatrix2fv_enc(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_value =  (count * 4 * sizeof(GLfloat));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 1 + __size_value + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glUniformMatrix2fv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &location, 4); ptr += 4;
+		memcpy(ptr, &count, 4); ptr += 4;
+		memcpy(ptr, &transpose, 1); ptr += 1;
+	*(unsigned int *)(ptr) = __size_value; ptr += 4;
+	memcpy(ptr, value, __size_value);ptr += __size_value;
+}
+
+void glUniformMatrix3fv_enc(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_value =  (count * 9 * sizeof(GLfloat));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 1 + __size_value + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glUniformMatrix3fv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &location, 4); ptr += 4;
+		memcpy(ptr, &count, 4); ptr += 4;
+		memcpy(ptr, &transpose, 1); ptr += 1;
+	*(unsigned int *)(ptr) = __size_value; ptr += 4;
+	memcpy(ptr, value, __size_value);ptr += __size_value;
+}
+
+void glUniformMatrix4fv_enc(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_value =  (count * 16 * sizeof(GLfloat));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 1 + __size_value + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glUniformMatrix4fv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &location, 4); ptr += 4;
+		memcpy(ptr, &count, 4); ptr += 4;
+		memcpy(ptr, &transpose, 1); ptr += 1;
+	*(unsigned int *)(ptr) = __size_value; ptr += 4;
+	memcpy(ptr, value, __size_value);ptr += __size_value;
+}
+
+void glUseProgram_enc(void *self , GLuint program)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glUseProgram;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &program, 4); ptr += 4;
+}
+
+void glValidateProgram_enc(void *self , GLuint program)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glValidateProgram;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &program, 4); ptr += 4;
+}
+
+void glVertexAttrib1f_enc(void *self , GLuint indx, GLfloat x)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glVertexAttrib1f;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &indx, 4); ptr += 4;
+		memcpy(ptr, &x, 4); ptr += 4;
+}
+
+void glVertexAttrib1fv_enc(void *self , GLuint indx, const GLfloat* values)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_values =  (sizeof(GLfloat));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_values + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glVertexAttrib1fv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &indx, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_values; ptr += 4;
+	memcpy(ptr, values, __size_values);ptr += __size_values;
+}
+
+void glVertexAttrib2f_enc(void *self , GLuint indx, GLfloat x, GLfloat y)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glVertexAttrib2f;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &indx, 4); ptr += 4;
+		memcpy(ptr, &x, 4); ptr += 4;
+		memcpy(ptr, &y, 4); ptr += 4;
+}
+
+void glVertexAttrib2fv_enc(void *self , GLuint indx, const GLfloat* values)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_values =  (2 * sizeof(GLfloat));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_values + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glVertexAttrib2fv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &indx, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_values; ptr += 4;
+	memcpy(ptr, values, __size_values);ptr += __size_values;
+}
+
+void glVertexAttrib3f_enc(void *self , GLuint indx, GLfloat x, GLfloat y, GLfloat z)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glVertexAttrib3f;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &indx, 4); ptr += 4;
+		memcpy(ptr, &x, 4); ptr += 4;
+		memcpy(ptr, &y, 4); ptr += 4;
+		memcpy(ptr, &z, 4); ptr += 4;
+}
+
+void glVertexAttrib3fv_enc(void *self , GLuint indx, const GLfloat* values)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_values =  (3 * sizeof(GLfloat));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_values + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glVertexAttrib3fv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &indx, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_values; ptr += 4;
+	memcpy(ptr, values, __size_values);ptr += __size_values;
+}
+
+void glVertexAttrib4f_enc(void *self , GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glVertexAttrib4f;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &indx, 4); ptr += 4;
+		memcpy(ptr, &x, 4); ptr += 4;
+		memcpy(ptr, &y, 4); ptr += 4;
+		memcpy(ptr, &z, 4); ptr += 4;
+		memcpy(ptr, &w, 4); ptr += 4;
+}
+
+void glVertexAttrib4fv_enc(void *self , GLuint indx, const GLfloat* values)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_values =  (4 * sizeof(GLfloat));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_values + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glVertexAttrib4fv;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &indx, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_values; ptr += 4;
+	memcpy(ptr, values, __size_values);ptr += __size_values;
+}
+
+void glViewport_enc(void *self , GLint x, GLint y, GLsizei width, GLsizei height)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glViewport;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &x, 4); ptr += 4;
+		memcpy(ptr, &y, 4); ptr += 4;
+		memcpy(ptr, &width, 4); ptr += 4;
+		memcpy(ptr, &height, 4); ptr += 4;
+}
+
+void glEGLImageTargetTexture2DOES_enc(void *self , GLenum target, GLeglImageOES image)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glEGLImageTargetTexture2DOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &image, 4); ptr += 4;
+}
+
+void glEGLImageTargetRenderbufferStorageOES_enc(void *self , GLenum target, GLeglImageOES image)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glEGLImageTargetRenderbufferStorageOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &image, 4); ptr += 4;
+}
+
+GLboolean glUnmapBufferOES_enc(void *self , GLenum target)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glUnmapBufferOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+
+	GLboolean retval;
+	stream->readback(&retval, 1);
+	return retval;
+}
+
+void glTexImage3DOES_enc(void *self , GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_pixels = ((pixels != NULL) ?  pixelDataSize3D(self, width, height, depth, format, type, 0) : 0);
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + __size_pixels + 1*4;
+	ptr = stream->alloc(8 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4);
+	int tmp = OP_glTexImage3DOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &level, 4); ptr += 4;
+		memcpy(ptr, &internalformat, 4); ptr += 4;
+		memcpy(ptr, &width, 4); ptr += 4;
+		memcpy(ptr, &height, 4); ptr += 4;
+		memcpy(ptr, &depth, 4); ptr += 4;
+		memcpy(ptr, &border, 4); ptr += 4;
+		memcpy(ptr, &format, 4); ptr += 4;
+		memcpy(ptr, &type, 4); ptr += 4;
+	stream->flush();
+	stream->writeFully(&__size_pixels,4);
+	if (pixels != NULL) stream->writeFully(pixels, __size_pixels);
+}
+
+void glTexSubImage3DOES_enc(void *self , GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_pixels =  pixelDataSize3D(self, width, height, depth, format, type, 0);
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + __size_pixels + 1*4;
+	ptr = stream->alloc(8 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4);
+	int tmp = OP_glTexSubImage3DOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &level, 4); ptr += 4;
+		memcpy(ptr, &xoffset, 4); ptr += 4;
+		memcpy(ptr, &yoffset, 4); ptr += 4;
+		memcpy(ptr, &zoffset, 4); ptr += 4;
+		memcpy(ptr, &width, 4); ptr += 4;
+		memcpy(ptr, &height, 4); ptr += 4;
+		memcpy(ptr, &depth, 4); ptr += 4;
+		memcpy(ptr, &format, 4); ptr += 4;
+		memcpy(ptr, &type, 4); ptr += 4;
+	stream->flush();
+	stream->writeFully(&__size_pixels,4);
+	stream->writeFully(pixels, __size_pixels);
+}
+
+void glCopyTexSubImage3DOES_enc(void *self , GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glCopyTexSubImage3DOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &level, 4); ptr += 4;
+		memcpy(ptr, &xoffset, 4); ptr += 4;
+		memcpy(ptr, &yoffset, 4); ptr += 4;
+		memcpy(ptr, &zoffset, 4); ptr += 4;
+		memcpy(ptr, &x, 4); ptr += 4;
+		memcpy(ptr, &y, 4); ptr += 4;
+		memcpy(ptr, &width, 4); ptr += 4;
+		memcpy(ptr, &height, 4); ptr += 4;
+}
+
+void glCompressedTexImage3DOES_enc(void *self , GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_data =  imageSize;
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + __size_data + 1*4;
+	ptr = stream->alloc(8 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4);
+	int tmp = OP_glCompressedTexImage3DOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &level, 4); ptr += 4;
+		memcpy(ptr, &internalformat, 4); ptr += 4;
+		memcpy(ptr, &width, 4); ptr += 4;
+		memcpy(ptr, &height, 4); ptr += 4;
+		memcpy(ptr, &depth, 4); ptr += 4;
+		memcpy(ptr, &border, 4); ptr += 4;
+		memcpy(ptr, &imageSize, 4); ptr += 4;
+	stream->flush();
+	stream->writeFully(&__size_data,4);
+	stream->writeFully(data, __size_data);
+}
+
+void glCompressedTexSubImage3DOES_enc(void *self , GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_data =  imageSize;
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + __size_data + 1*4;
+	ptr = stream->alloc(8 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4);
+	int tmp = OP_glCompressedTexSubImage3DOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &level, 4); ptr += 4;
+		memcpy(ptr, &xoffset, 4); ptr += 4;
+		memcpy(ptr, &yoffset, 4); ptr += 4;
+		memcpy(ptr, &zoffset, 4); ptr += 4;
+		memcpy(ptr, &width, 4); ptr += 4;
+		memcpy(ptr, &height, 4); ptr += 4;
+		memcpy(ptr, &depth, 4); ptr += 4;
+		memcpy(ptr, &format, 4); ptr += 4;
+		memcpy(ptr, &imageSize, 4); ptr += 4;
+	stream->flush();
+	stream->writeFully(&__size_data,4);
+	stream->writeFully(data, __size_data);
+}
+
+void glFramebufferTexture3DOES_enc(void *self , GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glFramebufferTexture3DOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &attachment, 4); ptr += 4;
+		memcpy(ptr, &textarget, 4); ptr += 4;
+		memcpy(ptr, &texture, 4); ptr += 4;
+		memcpy(ptr, &level, 4); ptr += 4;
+		memcpy(ptr, &zoffset, 4); ptr += 4;
+}
+
+void glBindVertexArrayOES_enc(void *self , GLuint array)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glBindVertexArrayOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &array, 4); ptr += 4;
+}
+
+void glDeleteVertexArraysOES_enc(void *self , GLsizei n, const GLuint* arrays)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_arrays =  (n * sizeof(GLuint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_arrays + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glDeleteVertexArraysOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &n, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_arrays; ptr += 4;
+	memcpy(ptr, arrays, __size_arrays);ptr += __size_arrays;
+}
+
+void glGenVertexArraysOES_enc(void *self , GLsizei n, GLuint* arrays)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_arrays =  (n * sizeof(GLuint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_arrays + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGenVertexArraysOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &n, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_arrays; ptr += 4;
+	stream->readback(arrays, __size_arrays);
+}
+
+GLboolean glIsVertexArrayOES_enc(void *self , GLuint array)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glIsVertexArrayOES;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &array, 4); ptr += 4;
+
+	GLboolean retval;
+	stream->readback(&retval, 1);
+	return retval;
+}
+
+void glDiscardFramebufferEXT_enc(void *self , GLenum target, GLsizei numAttachments, const GLenum* attachments)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_attachments =  (numAttachments * sizeof(GLenum));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + __size_attachments + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glDiscardFramebufferEXT;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &target, 4); ptr += 4;
+		memcpy(ptr, &numAttachments, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_attachments; ptr += 4;
+	memcpy(ptr, attachments, __size_attachments);ptr += __size_attachments;
+}
+
+void glVertexAttribPointerData_enc(void *self , GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, void* data, GLuint datalen)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_data =  datalen;
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 1 + 4 + __size_data + 4 + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glVertexAttribPointerData;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &indx, 4); ptr += 4;
+		memcpy(ptr, &size, 4); ptr += 4;
+		memcpy(ptr, &type, 4); ptr += 4;
+		memcpy(ptr, &normalized, 1); ptr += 1;
+		memcpy(ptr, &stride, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_data; ptr += 4;
+	 glUtilsPackPointerData((unsigned char *)ptr, (unsigned char *)data, size, type, stride, datalen);ptr += __size_data;
+		memcpy(ptr, &datalen, 4); ptr += 4;
+}
+
+void glVertexAttribPointerOffset_enc(void *self , GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint offset)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 1 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glVertexAttribPointerOffset;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &indx, 4); ptr += 4;
+		memcpy(ptr, &size, 4); ptr += 4;
+		memcpy(ptr, &type, 4); ptr += 4;
+		memcpy(ptr, &normalized, 1); ptr += 1;
+		memcpy(ptr, &stride, 4); ptr += 4;
+		memcpy(ptr, &offset, 4); ptr += 4;
+}
+
+void glDrawElementsOffset_enc(void *self , GLenum mode, GLsizei count, GLenum type, GLuint offset)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glDrawElementsOffset;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &mode, 4); ptr += 4;
+		memcpy(ptr, &count, 4); ptr += 4;
+		memcpy(ptr, &type, 4); ptr += 4;
+		memcpy(ptr, &offset, 4); ptr += 4;
+}
+
+void glDrawElementsData_enc(void *self , GLenum mode, GLsizei count, GLenum type, void* data, GLuint datalen)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_data =  datalen;
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + __size_data + 4 + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glDrawElementsData;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &mode, 4); ptr += 4;
+		memcpy(ptr, &count, 4); ptr += 4;
+		memcpy(ptr, &type, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_data; ptr += 4;
+	memcpy(ptr, data, __size_data);ptr += __size_data;
+		memcpy(ptr, &datalen, 4); ptr += 4;
+}
+
+void glGetCompressedTextureFormats_enc(void *self , int count, GLint* formats)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_formats =  (count * sizeof(GLint));
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_formats + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glGetCompressedTextureFormats;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &count, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_formats; ptr += 4;
+	stream->readback(formats, __size_formats);
+}
+
+void glShaderString_enc(void *self , GLuint shader, const GLchar* string, GLsizei len)
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_string =  len;
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_string + 4 + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glShaderString;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &shader, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_string; ptr += 4;
+	memcpy(ptr, string, __size_string);ptr += __size_string;
+		memcpy(ptr, &len, 4); ptr += 4;
+}
+
+int glFinishRoundTrip_enc(void *self )
+{
+
+	gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 0;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_glFinishRoundTrip;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+
+	int retval;
+	stream->readback(&retval, 4);
+	return retval;
+}
+
+gl2_encoder_context_t::gl2_encoder_context_t(IOStream *stream)
+{
+	m_stream = stream;
+
+	set_glActiveTexture(glActiveTexture_enc);
+	set_glAttachShader(glAttachShader_enc);
+	set_glBindAttribLocation(glBindAttribLocation_enc);
+	set_glBindBuffer(glBindBuffer_enc);
+	set_glBindFramebuffer(glBindFramebuffer_enc);
+	set_glBindRenderbuffer(glBindRenderbuffer_enc);
+	set_glBindTexture(glBindTexture_enc);
+	set_glBlendColor(glBlendColor_enc);
+	set_glBlendEquation(glBlendEquation_enc);
+	set_glBlendEquationSeparate(glBlendEquationSeparate_enc);
+	set_glBlendFunc(glBlendFunc_enc);
+	set_glBlendFuncSeparate(glBlendFuncSeparate_enc);
+	set_glBufferData(glBufferData_enc);
+	set_glBufferSubData(glBufferSubData_enc);
+	set_glCheckFramebufferStatus(glCheckFramebufferStatus_enc);
+	set_glClear(glClear_enc);
+	set_glClearColor(glClearColor_enc);
+	set_glClearDepthf(glClearDepthf_enc);
+	set_glClearStencil(glClearStencil_enc);
+	set_glColorMask(glColorMask_enc);
+	set_glCompileShader(glCompileShader_enc);
+	set_glCompressedTexImage2D(glCompressedTexImage2D_enc);
+	set_glCompressedTexSubImage2D(glCompressedTexSubImage2D_enc);
+	set_glCopyTexImage2D(glCopyTexImage2D_enc);
+	set_glCopyTexSubImage2D(glCopyTexSubImage2D_enc);
+	set_glCreateProgram(glCreateProgram_enc);
+	set_glCreateShader(glCreateShader_enc);
+	set_glCullFace(glCullFace_enc);
+	set_glDeleteBuffers(glDeleteBuffers_enc);
+	set_glDeleteFramebuffers(glDeleteFramebuffers_enc);
+	set_glDeleteProgram(glDeleteProgram_enc);
+	set_glDeleteRenderbuffers(glDeleteRenderbuffers_enc);
+	set_glDeleteShader(glDeleteShader_enc);
+	set_glDeleteTextures(glDeleteTextures_enc);
+	set_glDepthFunc(glDepthFunc_enc);
+	set_glDepthMask(glDepthMask_enc);
+	set_glDepthRangef(glDepthRangef_enc);
+	set_glDetachShader(glDetachShader_enc);
+	set_glDisable(glDisable_enc);
+	set_glDisableVertexAttribArray(glDisableVertexAttribArray_enc);
+	set_glDrawArrays(glDrawArrays_enc);
+	set_glDrawElements((glDrawElements_client_proc_t)(enc_unsupported));
+	set_glEnable(glEnable_enc);
+	set_glEnableVertexAttribArray(glEnableVertexAttribArray_enc);
+	set_glFinish(glFinish_enc);
+	set_glFlush(glFlush_enc);
+	set_glFramebufferRenderbuffer(glFramebufferRenderbuffer_enc);
+	set_glFramebufferTexture2D(glFramebufferTexture2D_enc);
+	set_glFrontFace(glFrontFace_enc);
+	set_glGenBuffers(glGenBuffers_enc);
+	set_glGenerateMipmap(glGenerateMipmap_enc);
+	set_glGenFramebuffers(glGenFramebuffers_enc);
+	set_glGenRenderbuffers(glGenRenderbuffers_enc);
+	set_glGenTextures(glGenTextures_enc);
+	set_glGetActiveAttrib(glGetActiveAttrib_enc);
+	set_glGetActiveUniform(glGetActiveUniform_enc);
+	set_glGetAttachedShaders(glGetAttachedShaders_enc);
+	set_glGetAttribLocation(glGetAttribLocation_enc);
+	set_glGetBooleanv(glGetBooleanv_enc);
+	set_glGetBufferParameteriv(glGetBufferParameteriv_enc);
+	set_glGetError(glGetError_enc);
+	set_glGetFloatv(glGetFloatv_enc);
+	set_glGetFramebufferAttachmentParameteriv(glGetFramebufferAttachmentParameteriv_enc);
+	set_glGetIntegerv(glGetIntegerv_enc);
+	set_glGetProgramiv(glGetProgramiv_enc);
+	set_glGetProgramInfoLog(glGetProgramInfoLog_enc);
+	set_glGetRenderbufferParameteriv(glGetRenderbufferParameteriv_enc);
+	set_glGetShaderiv(glGetShaderiv_enc);
+	set_glGetShaderInfoLog(glGetShaderInfoLog_enc);
+	set_glGetShaderPrecisionFormat(glGetShaderPrecisionFormat_enc);
+	set_glGetShaderSource(glGetShaderSource_enc);
+	set_glGetString((glGetString_client_proc_t)(enc_unsupported));
+	set_glGetTexParameterfv(glGetTexParameterfv_enc);
+	set_glGetTexParameteriv(glGetTexParameteriv_enc);
+	set_glGetUniformfv(glGetUniformfv_enc);
+	set_glGetUniformiv(glGetUniformiv_enc);
+	set_glGetUniformLocation(glGetUniformLocation_enc);
+	set_glGetVertexAttribfv(glGetVertexAttribfv_enc);
+	set_glGetVertexAttribiv(glGetVertexAttribiv_enc);
+	set_glGetVertexAttribPointerv((glGetVertexAttribPointerv_client_proc_t)(enc_unsupported));
+	set_glHint(glHint_enc);
+	set_glIsBuffer(glIsBuffer_enc);
+	set_glIsEnabled(glIsEnabled_enc);
+	set_glIsFramebuffer(glIsFramebuffer_enc);
+	set_glIsProgram(glIsProgram_enc);
+	set_glIsRenderbuffer(glIsRenderbuffer_enc);
+	set_glIsShader(glIsShader_enc);
+	set_glIsTexture(glIsTexture_enc);
+	set_glLineWidth(glLineWidth_enc);
+	set_glLinkProgram(glLinkProgram_enc);
+	set_glPixelStorei(glPixelStorei_enc);
+	set_glPolygonOffset(glPolygonOffset_enc);
+	set_glReadPixels(glReadPixels_enc);
+	set_glReleaseShaderCompiler(glReleaseShaderCompiler_enc);
+	set_glRenderbufferStorage(glRenderbufferStorage_enc);
+	set_glSampleCoverage(glSampleCoverage_enc);
+	set_glScissor(glScissor_enc);
+	set_glShaderBinary((glShaderBinary_client_proc_t)(enc_unsupported));
+	set_glShaderSource((glShaderSource_client_proc_t)(enc_unsupported));
+	set_glStencilFunc(glStencilFunc_enc);
+	set_glStencilFuncSeparate(glStencilFuncSeparate_enc);
+	set_glStencilMask(glStencilMask_enc);
+	set_glStencilMaskSeparate(glStencilMaskSeparate_enc);
+	set_glStencilOp(glStencilOp_enc);
+	set_glStencilOpSeparate(glStencilOpSeparate_enc);
+	set_glTexImage2D(glTexImage2D_enc);
+	set_glTexParameterf(glTexParameterf_enc);
+	set_glTexParameterfv(glTexParameterfv_enc);
+	set_glTexParameteri(glTexParameteri_enc);
+	set_glTexParameteriv(glTexParameteriv_enc);
+	set_glTexSubImage2D(glTexSubImage2D_enc);
+	set_glUniform1f(glUniform1f_enc);
+	set_glUniform1fv(glUniform1fv_enc);
+	set_glUniform1i(glUniform1i_enc);
+	set_glUniform1iv(glUniform1iv_enc);
+	set_glUniform2f(glUniform2f_enc);
+	set_glUniform2fv(glUniform2fv_enc);
+	set_glUniform2i(glUniform2i_enc);
+	set_glUniform2iv(glUniform2iv_enc);
+	set_glUniform3f(glUniform3f_enc);
+	set_glUniform3fv(glUniform3fv_enc);
+	set_glUniform3i(glUniform3i_enc);
+	set_glUniform3iv(glUniform3iv_enc);
+	set_glUniform4f(glUniform4f_enc);
+	set_glUniform4fv(glUniform4fv_enc);
+	set_glUniform4i(glUniform4i_enc);
+	set_glUniform4iv(glUniform4iv_enc);
+	set_glUniformMatrix2fv(glUniformMatrix2fv_enc);
+	set_glUniformMatrix3fv(glUniformMatrix3fv_enc);
+	set_glUniformMatrix4fv(glUniformMatrix4fv_enc);
+	set_glUseProgram(glUseProgram_enc);
+	set_glValidateProgram(glValidateProgram_enc);
+	set_glVertexAttrib1f(glVertexAttrib1f_enc);
+	set_glVertexAttrib1fv(glVertexAttrib1fv_enc);
+	set_glVertexAttrib2f(glVertexAttrib2f_enc);
+	set_glVertexAttrib2fv(glVertexAttrib2fv_enc);
+	set_glVertexAttrib3f(glVertexAttrib3f_enc);
+	set_glVertexAttrib3fv(glVertexAttrib3fv_enc);
+	set_glVertexAttrib4f(glVertexAttrib4f_enc);
+	set_glVertexAttrib4fv(glVertexAttrib4fv_enc);
+	set_glVertexAttribPointer((glVertexAttribPointer_client_proc_t)(enc_unsupported));
+	set_glViewport(glViewport_enc);
+	set_glEGLImageTargetTexture2DOES(glEGLImageTargetTexture2DOES_enc);
+	set_glEGLImageTargetRenderbufferStorageOES(glEGLImageTargetRenderbufferStorageOES_enc);
+	set_glGetProgramBinaryOES((glGetProgramBinaryOES_client_proc_t)(enc_unsupported));
+	set_glProgramBinaryOES((glProgramBinaryOES_client_proc_t)(enc_unsupported));
+	set_glMapBufferOES((glMapBufferOES_client_proc_t)(enc_unsupported));
+	set_glUnmapBufferOES(glUnmapBufferOES_enc);
+	set_glTexImage3DOES(glTexImage3DOES_enc);
+	set_glTexSubImage3DOES(glTexSubImage3DOES_enc);
+	set_glCopyTexSubImage3DOES(glCopyTexSubImage3DOES_enc);
+	set_glCompressedTexImage3DOES(glCompressedTexImage3DOES_enc);
+	set_glCompressedTexSubImage3DOES(glCompressedTexSubImage3DOES_enc);
+	set_glFramebufferTexture3DOES(glFramebufferTexture3DOES_enc);
+	set_glBindVertexArrayOES(glBindVertexArrayOES_enc);
+	set_glDeleteVertexArraysOES(glDeleteVertexArraysOES_enc);
+	set_glGenVertexArraysOES(glGenVertexArraysOES_enc);
+	set_glIsVertexArrayOES(glIsVertexArrayOES_enc);
+	set_glDiscardFramebufferEXT(glDiscardFramebufferEXT_enc);
+	set_glMultiDrawArraysEXT((glMultiDrawArraysEXT_client_proc_t)(enc_unsupported));
+	set_glMultiDrawElementsEXT((glMultiDrawElementsEXT_client_proc_t)(enc_unsupported));
+	set_glGetPerfMonitorGroupsAMD((glGetPerfMonitorGroupsAMD_client_proc_t)(enc_unsupported));
+	set_glGetPerfMonitorCountersAMD((glGetPerfMonitorCountersAMD_client_proc_t)(enc_unsupported));
+	set_glGetPerfMonitorGroupStringAMD((glGetPerfMonitorGroupStringAMD_client_proc_t)(enc_unsupported));
+	set_glGetPerfMonitorCounterStringAMD((glGetPerfMonitorCounterStringAMD_client_proc_t)(enc_unsupported));
+	set_glGetPerfMonitorCounterInfoAMD((glGetPerfMonitorCounterInfoAMD_client_proc_t)(enc_unsupported));
+	set_glGenPerfMonitorsAMD((glGenPerfMonitorsAMD_client_proc_t)(enc_unsupported));
+	set_glDeletePerfMonitorsAMD((glDeletePerfMonitorsAMD_client_proc_t)(enc_unsupported));
+	set_glSelectPerfMonitorCountersAMD((glSelectPerfMonitorCountersAMD_client_proc_t)(enc_unsupported));
+	set_glBeginPerfMonitorAMD((glBeginPerfMonitorAMD_client_proc_t)(enc_unsupported));
+	set_glEndPerfMonitorAMD((glEndPerfMonitorAMD_client_proc_t)(enc_unsupported));
+	set_glGetPerfMonitorCounterDataAMD((glGetPerfMonitorCounterDataAMD_client_proc_t)(enc_unsupported));
+	set_glRenderbufferStorageMultisampleIMG((glRenderbufferStorageMultisampleIMG_client_proc_t)(enc_unsupported));
+	set_glFramebufferTexture2DMultisampleIMG((glFramebufferTexture2DMultisampleIMG_client_proc_t)(enc_unsupported));
+	set_glDeleteFencesNV((glDeleteFencesNV_client_proc_t)(enc_unsupported));
+	set_glGenFencesNV((glGenFencesNV_client_proc_t)(enc_unsupported));
+	set_glIsFenceNV((glIsFenceNV_client_proc_t)(enc_unsupported));
+	set_glTestFenceNV((glTestFenceNV_client_proc_t)(enc_unsupported));
+	set_glGetFenceivNV((glGetFenceivNV_client_proc_t)(enc_unsupported));
+	set_glFinishFenceNV((glFinishFenceNV_client_proc_t)(enc_unsupported));
+	set_glSetFenceNV((glSetFenceNV_client_proc_t)(enc_unsupported));
+	set_glCoverageMaskNV((glCoverageMaskNV_client_proc_t)(enc_unsupported));
+	set_glCoverageOperationNV((glCoverageOperationNV_client_proc_t)(enc_unsupported));
+	set_glGetDriverControlsQCOM((glGetDriverControlsQCOM_client_proc_t)(enc_unsupported));
+	set_glGetDriverControlStringQCOM((glGetDriverControlStringQCOM_client_proc_t)(enc_unsupported));
+	set_glEnableDriverControlQCOM((glEnableDriverControlQCOM_client_proc_t)(enc_unsupported));
+	set_glDisableDriverControlQCOM((glDisableDriverControlQCOM_client_proc_t)(enc_unsupported));
+	set_glExtGetTexturesQCOM((glExtGetTexturesQCOM_client_proc_t)(enc_unsupported));
+	set_glExtGetBuffersQCOM((glExtGetBuffersQCOM_client_proc_t)(enc_unsupported));
+	set_glExtGetRenderbuffersQCOM((glExtGetRenderbuffersQCOM_client_proc_t)(enc_unsupported));
+	set_glExtGetFramebuffersQCOM((glExtGetFramebuffersQCOM_client_proc_t)(enc_unsupported));
+	set_glExtGetTexLevelParameterivQCOM((glExtGetTexLevelParameterivQCOM_client_proc_t)(enc_unsupported));
+	set_glExtTexObjectStateOverrideiQCOM((glExtTexObjectStateOverrideiQCOM_client_proc_t)(enc_unsupported));
+	set_glExtGetTexSubImageQCOM((glExtGetTexSubImageQCOM_client_proc_t)(enc_unsupported));
+	set_glExtGetBufferPointervQCOM((glExtGetBufferPointervQCOM_client_proc_t)(enc_unsupported));
+	set_glExtGetShadersQCOM((glExtGetShadersQCOM_client_proc_t)(enc_unsupported));
+	set_glExtGetProgramsQCOM((glExtGetProgramsQCOM_client_proc_t)(enc_unsupported));
+	set_glExtIsProgramBinaryQCOM((glExtIsProgramBinaryQCOM_client_proc_t)(enc_unsupported));
+	set_glExtGetProgramBinarySourceQCOM((glExtGetProgramBinarySourceQCOM_client_proc_t)(enc_unsupported));
+	set_glStartTilingQCOM((glStartTilingQCOM_client_proc_t)(enc_unsupported));
+	set_glEndTilingQCOM((glEndTilingQCOM_client_proc_t)(enc_unsupported));
+	set_glVertexAttribPointerData(glVertexAttribPointerData_enc);
+	set_glVertexAttribPointerOffset(glVertexAttribPointerOffset_enc);
+	set_glDrawElementsOffset(glDrawElementsOffset_enc);
+	set_glDrawElementsData(glDrawElementsData_enc);
+	set_glGetCompressedTextureFormats(glGetCompressedTextureFormats_enc);
+	set_glShaderString(glShaderString_enc);
+	set_glFinishRoundTrip(glFinishRoundTrip_enc);
+}
+
diff --git a/opengl/system/GLESv2_enc/gl2_enc.h b/opengl/system/GLESv2_enc/gl2_enc.h
new file mode 100644
index 0000000..b1b456a
--- /dev/null
+++ b/opengl/system/GLESv2_enc/gl2_enc.h
@@ -0,0 +1,234 @@
+// Generated Code - DO NOT EDIT !!
+// generated by 'emugen'
+
+#ifndef GUARD_gl2_encoder_context_t
+#define GUARD_gl2_encoder_context_t
+
+#include "IOStream.h"
+#include "gl2_client_context.h"
+
+
+#include <string.h>
+#include "glUtils.h"
+#include "GL2EncoderUtils.h"
+
+struct gl2_encoder_context_t : public gl2_client_context_t {
+
+	IOStream *m_stream;
+
+	gl2_encoder_context_t(IOStream *stream);
+
+
+};
+
+extern "C" {
+	void glActiveTexture_enc(void *self , GLenum texture);
+	void glAttachShader_enc(void *self , GLuint program, GLuint shader);
+	void glBindAttribLocation_enc(void *self , GLuint program, GLuint index, const GLchar* name);
+	void glBindBuffer_enc(void *self , GLenum target, GLuint buffer);
+	void glBindFramebuffer_enc(void *self , GLenum target, GLuint framebuffer);
+	void glBindRenderbuffer_enc(void *self , GLenum target, GLuint renderbuffer);
+	void glBindTexture_enc(void *self , GLenum target, GLuint texture);
+	void glBlendColor_enc(void *self , GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+	void glBlendEquation_enc(void *self , GLenum mode);
+	void glBlendEquationSeparate_enc(void *self , GLenum modeRGB, GLenum modeAlpha);
+	void glBlendFunc_enc(void *self , GLenum sfactor, GLenum dfactor);
+	void glBlendFuncSeparate_enc(void *self , GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+	void glBufferData_enc(void *self , GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage);
+	void glBufferSubData_enc(void *self , GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data);
+	GLenum glCheckFramebufferStatus_enc(void *self , GLenum target);
+	void glClear_enc(void *self , GLbitfield mask);
+	void glClearColor_enc(void *self , GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+	void glClearDepthf_enc(void *self , GLclampf depth);
+	void glClearStencil_enc(void *self , GLint s);
+	void glColorMask_enc(void *self , GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+	void glCompileShader_enc(void *self , GLuint shader);
+	void glCompressedTexImage2D_enc(void *self , GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data);
+	void glCompressedTexSubImage2D_enc(void *self , GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data);
+	void glCopyTexImage2D_enc(void *self , GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+	void glCopyTexSubImage2D_enc(void *self , GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+	GLuint glCreateProgram_enc(void *self );
+	GLuint glCreateShader_enc(void *self , GLenum type);
+	void glCullFace_enc(void *self , GLenum mode);
+	void glDeleteBuffers_enc(void *self , GLsizei n, const GLuint* buffers);
+	void glDeleteFramebuffers_enc(void *self , GLsizei n, const GLuint* framebuffers);
+	void glDeleteProgram_enc(void *self , GLuint program);
+	void glDeleteRenderbuffers_enc(void *self , GLsizei n, const GLuint* renderbuffers);
+	void glDeleteShader_enc(void *self , GLuint shader);
+	void glDeleteTextures_enc(void *self , GLsizei n, const GLuint* textures);
+	void glDepthFunc_enc(void *self , GLenum func);
+	void glDepthMask_enc(void *self , GLboolean flag);
+	void glDepthRangef_enc(void *self , GLclampf zNear, GLclampf zFar);
+	void glDetachShader_enc(void *self , GLuint program, GLuint shader);
+	void glDisable_enc(void *self , GLenum cap);
+	void glDisableVertexAttribArray_enc(void *self , GLuint index);
+	void glDrawArrays_enc(void *self , GLenum mode, GLint first, GLsizei count);
+	void glDrawElements_enc(void *self , GLenum mode, GLsizei count, GLenum type, const GLvoid* indices);
+	void glEnable_enc(void *self , GLenum cap);
+	void glEnableVertexAttribArray_enc(void *self , GLuint index);
+	void glFinish_enc(void *self );
+	void glFlush_enc(void *self );
+	void glFramebufferRenderbuffer_enc(void *self , GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+	void glFramebufferTexture2D_enc(void *self , GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+	void glFrontFace_enc(void *self , GLenum mode);
+	void glGenBuffers_enc(void *self , GLsizei n, GLuint* buffers);
+	void glGenerateMipmap_enc(void *self , GLenum target);
+	void glGenFramebuffers_enc(void *self , GLsizei n, GLuint* framebuffers);
+	void glGenRenderbuffers_enc(void *self , GLsizei n, GLuint* renderbuffers);
+	void glGenTextures_enc(void *self , GLsizei n, GLuint* textures);
+	void glGetActiveAttrib_enc(void *self , GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
+	void glGetActiveUniform_enc(void *self , GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
+	void glGetAttachedShaders_enc(void *self , GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders);
+	int glGetAttribLocation_enc(void *self , GLuint program, const GLchar* name);
+	void glGetBooleanv_enc(void *self , GLenum pname, GLboolean* params);
+	void glGetBufferParameteriv_enc(void *self , GLenum target, GLenum pname, GLint* params);
+	GLenum glGetError_enc(void *self );
+	void glGetFloatv_enc(void *self , GLenum pname, GLfloat* params);
+	void glGetFramebufferAttachmentParameteriv_enc(void *self , GLenum target, GLenum attachment, GLenum pname, GLint* params);
+	void glGetIntegerv_enc(void *self , GLenum pname, GLint* params);
+	void glGetProgramiv_enc(void *self , GLuint program, GLenum pname, GLint* params);
+	void glGetProgramInfoLog_enc(void *self , GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog);
+	void glGetRenderbufferParameteriv_enc(void *self , GLenum target, GLenum pname, GLint* params);
+	void glGetShaderiv_enc(void *self , GLuint shader, GLenum pname, GLint* params);
+	void glGetShaderInfoLog_enc(void *self , GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog);
+	void glGetShaderPrecisionFormat_enc(void *self , GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision);
+	void glGetShaderSource_enc(void *self , GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source);
+	const GLubyte* glGetString_enc(void *self , GLenum name);
+	void glGetTexParameterfv_enc(void *self , GLenum target, GLenum pname, GLfloat* params);
+	void glGetTexParameteriv_enc(void *self , GLenum target, GLenum pname, GLint* params);
+	void glGetUniformfv_enc(void *self , GLuint program, GLint location, GLfloat* params);
+	void glGetUniformiv_enc(void *self , GLuint program, GLint location, GLint* params);
+	int glGetUniformLocation_enc(void *self , GLuint program, const GLchar* name);
+	void glGetVertexAttribfv_enc(void *self , GLuint index, GLenum pname, GLfloat* params);
+	void glGetVertexAttribiv_enc(void *self , GLuint index, GLenum pname, GLint* params);
+	void glGetVertexAttribPointerv_enc(void *self , GLuint index, GLenum pname, GLvoid** pointer);
+	void glHint_enc(void *self , GLenum target, GLenum mode);
+	GLboolean glIsBuffer_enc(void *self , GLuint buffer);
+	GLboolean glIsEnabled_enc(void *self , GLenum cap);
+	GLboolean glIsFramebuffer_enc(void *self , GLuint framebuffer);
+	GLboolean glIsProgram_enc(void *self , GLuint program);
+	GLboolean glIsRenderbuffer_enc(void *self , GLuint renderbuffer);
+	GLboolean glIsShader_enc(void *self , GLuint shader);
+	GLboolean glIsTexture_enc(void *self , GLuint texture);
+	void glLineWidth_enc(void *self , GLfloat width);
+	void glLinkProgram_enc(void *self , GLuint program);
+	void glPixelStorei_enc(void *self , GLenum pname, GLint param);
+	void glPolygonOffset_enc(void *self , GLfloat factor, GLfloat units);
+	void glReadPixels_enc(void *self , GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels);
+	void glReleaseShaderCompiler_enc(void *self );
+	void glRenderbufferStorage_enc(void *self , GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+	void glSampleCoverage_enc(void *self , GLclampf value, GLboolean invert);
+	void glScissor_enc(void *self , GLint x, GLint y, GLsizei width, GLsizei height);
+	void glShaderBinary_enc(void *self , GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length);
+	void glShaderSource_enc(void *self , GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length);
+	void glStencilFunc_enc(void *self , GLenum func, GLint ref, GLuint mask);
+	void glStencilFuncSeparate_enc(void *self , GLenum face, GLenum func, GLint ref, GLuint mask);
+	void glStencilMask_enc(void *self , GLuint mask);
+	void glStencilMaskSeparate_enc(void *self , GLenum face, GLuint mask);
+	void glStencilOp_enc(void *self , GLenum fail, GLenum zfail, GLenum zpass);
+	void glStencilOpSeparate_enc(void *self , GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
+	void glTexImage2D_enc(void *self , GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels);
+	void glTexParameterf_enc(void *self , GLenum target, GLenum pname, GLfloat param);
+	void glTexParameterfv_enc(void *self , GLenum target, GLenum pname, const GLfloat* params);
+	void glTexParameteri_enc(void *self , GLenum target, GLenum pname, GLint param);
+	void glTexParameteriv_enc(void *self , GLenum target, GLenum pname, const GLint* params);
+	void glTexSubImage2D_enc(void *self , GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels);
+	void glUniform1f_enc(void *self , GLint location, GLfloat x);
+	void glUniform1fv_enc(void *self , GLint location, GLsizei count, const GLfloat* v);
+	void glUniform1i_enc(void *self , GLint location, GLint x);
+	void glUniform1iv_enc(void *self , GLint location, GLsizei count, const GLint* v);
+	void glUniform2f_enc(void *self , GLint location, GLfloat x, GLfloat y);
+	void glUniform2fv_enc(void *self , GLint location, GLsizei count, const GLfloat* v);
+	void glUniform2i_enc(void *self , GLint location, GLint x, GLint y);
+	void glUniform2iv_enc(void *self , GLint location, GLsizei count, const GLint* v);
+	void glUniform3f_enc(void *self , GLint location, GLfloat x, GLfloat y, GLfloat z);
+	void glUniform3fv_enc(void *self , GLint location, GLsizei count, const GLfloat* v);
+	void glUniform3i_enc(void *self , GLint location, GLint x, GLint y, GLint z);
+	void glUniform3iv_enc(void *self , GLint location, GLsizei count, const GLint* v);
+	void glUniform4f_enc(void *self , GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+	void glUniform4fv_enc(void *self , GLint location, GLsizei count, const GLfloat* v);
+	void glUniform4i_enc(void *self , GLint location, GLint x, GLint y, GLint z, GLint w);
+	void glUniform4iv_enc(void *self , GLint location, GLsizei count, const GLint* v);
+	void glUniformMatrix2fv_enc(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+	void glUniformMatrix3fv_enc(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+	void glUniformMatrix4fv_enc(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+	void glUseProgram_enc(void *self , GLuint program);
+	void glValidateProgram_enc(void *self , GLuint program);
+	void glVertexAttrib1f_enc(void *self , GLuint indx, GLfloat x);
+	void glVertexAttrib1fv_enc(void *self , GLuint indx, const GLfloat* values);
+	void glVertexAttrib2f_enc(void *self , GLuint indx, GLfloat x, GLfloat y);
+	void glVertexAttrib2fv_enc(void *self , GLuint indx, const GLfloat* values);
+	void glVertexAttrib3f_enc(void *self , GLuint indx, GLfloat x, GLfloat y, GLfloat z);
+	void glVertexAttrib3fv_enc(void *self , GLuint indx, const GLfloat* values);
+	void glVertexAttrib4f_enc(void *self , GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+	void glVertexAttrib4fv_enc(void *self , GLuint indx, const GLfloat* values);
+	void glVertexAttribPointer_enc(void *self , GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr);
+	void glViewport_enc(void *self , GLint x, GLint y, GLsizei width, GLsizei height);
+	void glEGLImageTargetTexture2DOES_enc(void *self , GLenum target, GLeglImageOES image);
+	void glEGLImageTargetRenderbufferStorageOES_enc(void *self , GLenum target, GLeglImageOES image);
+	void glGetProgramBinaryOES_enc(void *self , GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary);
+	void glProgramBinaryOES_enc(void *self , GLuint program, GLenum binaryFormat, const GLvoid* binary, GLint length);
+	void* glMapBufferOES_enc(void *self , GLenum target, GLenum access);
+	GLboolean glUnmapBufferOES_enc(void *self , GLenum target);
+	void glTexImage3DOES_enc(void *self , GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels);
+	void glTexSubImage3DOES_enc(void *self , GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels);
+	void glCopyTexSubImage3DOES_enc(void *self , GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+	void glCompressedTexImage3DOES_enc(void *self , GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data);
+	void glCompressedTexSubImage3DOES_enc(void *self , GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data);
+	void glFramebufferTexture3DOES_enc(void *self , GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+	void glBindVertexArrayOES_enc(void *self , GLuint array);
+	void glDeleteVertexArraysOES_enc(void *self , GLsizei n, const GLuint* arrays);
+	void glGenVertexArraysOES_enc(void *self , GLsizei n, GLuint* arrays);
+	GLboolean glIsVertexArrayOES_enc(void *self , GLuint array);
+	void glDiscardFramebufferEXT_enc(void *self , GLenum target, GLsizei numAttachments, const GLenum* attachments);
+	void glMultiDrawArraysEXT_enc(void *self , GLenum mode, GLint* first, GLsizei* count, GLsizei primcount);
+	void glMultiDrawElementsEXT_enc(void *self , GLenum mode, const GLsizei* count, GLenum type, const GLvoid** indices, GLsizei primcount);
+	void glGetPerfMonitorGroupsAMD_enc(void *self , GLint* numGroups, GLsizei groupsSize, GLuint* groups);
+	void glGetPerfMonitorCountersAMD_enc(void *self , GLuint group, GLint* numCounters, GLint* maxActiveCounters, GLsizei counterSize, GLuint* counters);
+	void glGetPerfMonitorGroupStringAMD_enc(void *self , GLuint group, GLsizei bufSize, GLsizei* length, GLchar* groupString);
+	void glGetPerfMonitorCounterStringAMD_enc(void *self , GLuint group, GLuint counter, GLsizei bufSize, GLsizei* length, GLchar* counterString);
+	void glGetPerfMonitorCounterInfoAMD_enc(void *self , GLuint group, GLuint counter, GLenum pname, GLvoid* data);
+	void glGenPerfMonitorsAMD_enc(void *self , GLsizei n, GLuint* monitors);
+	void glDeletePerfMonitorsAMD_enc(void *self , GLsizei n, GLuint* monitors);
+	void glSelectPerfMonitorCountersAMD_enc(void *self , GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint* countersList);
+	void glBeginPerfMonitorAMD_enc(void *self , GLuint monitor);
+	void glEndPerfMonitorAMD_enc(void *self , GLuint monitor);
+	void glGetPerfMonitorCounterDataAMD_enc(void *self , GLuint monitor, GLenum pname, GLsizei dataSize, GLuint* data, GLint* bytesWritten);
+	void glRenderbufferStorageMultisampleIMG_enc(void *self , GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+	void glFramebufferTexture2DMultisampleIMG_enc(void *self , GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples);
+	void glDeleteFencesNV_enc(void *self , GLsizei n, const GLuint* fences);
+	void glGenFencesNV_enc(void *self , GLsizei n, GLuint* fences);
+	GLboolean glIsFenceNV_enc(void *self , GLuint fence);
+	GLboolean glTestFenceNV_enc(void *self , GLuint fence);
+	void glGetFenceivNV_enc(void *self , GLuint fence, GLenum pname, GLint* params);
+	void glFinishFenceNV_enc(void *self , GLuint fence);
+	void glSetFenceNV_enc(void *self , GLuint fence, GLenum condition);
+	void glCoverageMaskNV_enc(void *self , GLboolean mask);
+	void glCoverageOperationNV_enc(void *self , GLenum operation);
+	void glGetDriverControlsQCOM_enc(void *self , GLint* num, GLsizei size, GLuint* driverControls);
+	void glGetDriverControlStringQCOM_enc(void *self , GLuint driverControl, GLsizei bufSize, GLsizei* length, GLchar* driverControlString);
+	void glEnableDriverControlQCOM_enc(void *self , GLuint driverControl);
+	void glDisableDriverControlQCOM_enc(void *self , GLuint driverControl);
+	void glExtGetTexturesQCOM_enc(void *self , GLuint* textures, GLint maxTextures, GLint* numTextures);
+	void glExtGetBuffersQCOM_enc(void *self , GLuint* buffers, GLint maxBuffers, GLint* numBuffers);
+	void glExtGetRenderbuffersQCOM_enc(void *self , GLuint* renderbuffers, GLint maxRenderbuffers, GLint* numRenderbuffers);
+	void glExtGetFramebuffersQCOM_enc(void *self , GLuint* framebuffers, GLint maxFramebuffers, GLint* numFramebuffers);
+	void glExtGetTexLevelParameterivQCOM_enc(void *self , GLuint texture, GLenum face, GLint level, GLenum pname, GLint* params);
+	void glExtTexObjectStateOverrideiQCOM_enc(void *self , GLenum target, GLenum pname, GLint param);
+	void glExtGetTexSubImageQCOM_enc(void *self , GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid* texels);
+	void glExtGetBufferPointervQCOM_enc(void *self , GLenum target, GLvoidptr* params);
+	void glExtGetShadersQCOM_enc(void *self , GLuint* shaders, GLint maxShaders, GLint* numShaders);
+	void glExtGetProgramsQCOM_enc(void *self , GLuint* programs, GLint maxPrograms, GLint* numPrograms);
+	GLboolean glExtIsProgramBinaryQCOM_enc(void *self , GLuint program);
+	void glExtGetProgramBinarySourceQCOM_enc(void *self , GLuint program, GLenum shadertype, GLchar* source, GLint* length);
+	void glStartTilingQCOM_enc(void *self , GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask);
+	void glEndTilingQCOM_enc(void *self , GLbitfield preserveMask);
+	void glVertexAttribPointerData_enc(void *self , GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, void* data, GLuint datalen);
+	void glVertexAttribPointerOffset_enc(void *self , GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint offset);
+	void glDrawElementsOffset_enc(void *self , GLenum mode, GLsizei count, GLenum type, GLuint offset);
+	void glDrawElementsData_enc(void *self , GLenum mode, GLsizei count, GLenum type, void* data, GLuint datalen);
+	void glGetCompressedTextureFormats_enc(void *self , int count, GLint* formats);
+	void glShaderString_enc(void *self , GLuint shader, const GLchar* string, GLsizei len);
+	int glFinishRoundTrip_enc(void *self );
+};
+#endif
diff --git a/opengl/system/GLESv2_enc/gl2_entry.cpp b/opengl/system/GLESv2_enc/gl2_entry.cpp
new file mode 100644
index 0000000..abd374b
--- /dev/null
+++ b/opengl/system/GLESv2_enc/gl2_entry.cpp
@@ -0,0 +1,1483 @@
+// Generated Code - DO NOT EDIT !!
+// generated by 'emugen'
+#include <stdio.h>
+#include <stdlib.h>
+#include "gl2_client_context.h"
+
+#ifndef GL_TRUE
+extern "C" {
+	void glActiveTexture(GLenum texture);
+	void glAttachShader(GLuint program, GLuint shader);
+	void glBindAttribLocation(GLuint program, GLuint index, const GLchar* name);
+	void glBindBuffer(GLenum target, GLuint buffer);
+	void glBindFramebuffer(GLenum target, GLuint framebuffer);
+	void glBindRenderbuffer(GLenum target, GLuint renderbuffer);
+	void glBindTexture(GLenum target, GLuint texture);
+	void glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+	void glBlendEquation(GLenum mode);
+	void glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);
+	void glBlendFunc(GLenum sfactor, GLenum dfactor);
+	void glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+	void glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage);
+	void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data);
+	GLenum glCheckFramebufferStatus(GLenum target);
+	void glClear(GLbitfield mask);
+	void glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+	void glClearDepthf(GLclampf depth);
+	void glClearStencil(GLint s);
+	void glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+	void glCompileShader(GLuint shader);
+	void glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data);
+	void glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data);
+	void glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+	void glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+	GLuint glCreateProgram();
+	GLuint glCreateShader(GLenum type);
+	void glCullFace(GLenum mode);
+	void glDeleteBuffers(GLsizei n, const GLuint* buffers);
+	void glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers);
+	void glDeleteProgram(GLuint program);
+	void glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers);
+	void glDeleteShader(GLuint shader);
+	void glDeleteTextures(GLsizei n, const GLuint* textures);
+	void glDepthFunc(GLenum func);
+	void glDepthMask(GLboolean flag);
+	void glDepthRangef(GLclampf zNear, GLclampf zFar);
+	void glDetachShader(GLuint program, GLuint shader);
+	void glDisable(GLenum cap);
+	void glDisableVertexAttribArray(GLuint index);
+	void glDrawArrays(GLenum mode, GLint first, GLsizei count);
+	void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices);
+	void glEnable(GLenum cap);
+	void glEnableVertexAttribArray(GLuint index);
+	void glFinish();
+	void glFlush();
+	void glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+	void glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+	void glFrontFace(GLenum mode);
+	void glGenBuffers(GLsizei n, GLuint* buffers);
+	void glGenerateMipmap(GLenum target);
+	void glGenFramebuffers(GLsizei n, GLuint* framebuffers);
+	void glGenRenderbuffers(GLsizei n, GLuint* renderbuffers);
+	void glGenTextures(GLsizei n, GLuint* textures);
+	void glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
+	void glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
+	void glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders);
+	int glGetAttribLocation(GLuint program, const GLchar* name);
+	void glGetBooleanv(GLenum pname, GLboolean* params);
+	void glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params);
+	GLenum glGetError();
+	void glGetFloatv(GLenum pname, GLfloat* params);
+	void glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params);
+	void glGetIntegerv(GLenum pname, GLint* params);
+	void glGetProgramiv(GLuint program, GLenum pname, GLint* params);
+	void glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog);
+	void glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params);
+	void glGetShaderiv(GLuint shader, GLenum pname, GLint* params);
+	void glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog);
+	void glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision);
+	void glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source);
+	const GLubyte* glGetString(GLenum name);
+	void glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params);
+	void glGetTexParameteriv(GLenum target, GLenum pname, GLint* params);
+	void glGetUniformfv(GLuint program, GLint location, GLfloat* params);
+	void glGetUniformiv(GLuint program, GLint location, GLint* params);
+	int glGetUniformLocation(GLuint program, const GLchar* name);
+	void glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params);
+	void glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params);
+	void glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer);
+	void glHint(GLenum target, GLenum mode);
+	GLboolean glIsBuffer(GLuint buffer);
+	GLboolean glIsEnabled(GLenum cap);
+	GLboolean glIsFramebuffer(GLuint framebuffer);
+	GLboolean glIsProgram(GLuint program);
+	GLboolean glIsRenderbuffer(GLuint renderbuffer);
+	GLboolean glIsShader(GLuint shader);
+	GLboolean glIsTexture(GLuint texture);
+	void glLineWidth(GLfloat width);
+	void glLinkProgram(GLuint program);
+	void glPixelStorei(GLenum pname, GLint param);
+	void glPolygonOffset(GLfloat factor, GLfloat units);
+	void glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels);
+	void glReleaseShaderCompiler();
+	void glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+	void glSampleCoverage(GLclampf value, GLboolean invert);
+	void glScissor(GLint x, GLint y, GLsizei width, GLsizei height);
+	void glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length);
+	void glShaderSource(GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length);
+	void glStencilFunc(GLenum func, GLint ref, GLuint mask);
+	void glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
+	void glStencilMask(GLuint mask);
+	void glStencilMaskSeparate(GLenum face, GLuint mask);
+	void glStencilOp(GLenum fail, GLenum zfail, GLenum zpass);
+	void glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
+	void glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels);
+	void glTexParameterf(GLenum target, GLenum pname, GLfloat param);
+	void glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
+	void glTexParameteri(GLenum target, GLenum pname, GLint param);
+	void glTexParameteriv(GLenum target, GLenum pname, const GLint* params);
+	void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels);
+	void glUniform1f(GLint location, GLfloat x);
+	void glUniform1fv(GLint location, GLsizei count, const GLfloat* v);
+	void glUniform1i(GLint location, GLint x);
+	void glUniform1iv(GLint location, GLsizei count, const GLint* v);
+	void glUniform2f(GLint location, GLfloat x, GLfloat y);
+	void glUniform2fv(GLint location, GLsizei count, const GLfloat* v);
+	void glUniform2i(GLint location, GLint x, GLint y);
+	void glUniform2iv(GLint location, GLsizei count, const GLint* v);
+	void glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z);
+	void glUniform3fv(GLint location, GLsizei count, const GLfloat* v);
+	void glUniform3i(GLint location, GLint x, GLint y, GLint z);
+	void glUniform3iv(GLint location, GLsizei count, const GLint* v);
+	void glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+	void glUniform4fv(GLint location, GLsizei count, const GLfloat* v);
+	void glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w);
+	void glUniform4iv(GLint location, GLsizei count, const GLint* v);
+	void glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+	void glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+	void glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+	void glUseProgram(GLuint program);
+	void glValidateProgram(GLuint program);
+	void glVertexAttrib1f(GLuint indx, GLfloat x);
+	void glVertexAttrib1fv(GLuint indx, const GLfloat* values);
+	void glVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y);
+	void glVertexAttrib2fv(GLuint indx, const GLfloat* values);
+	void glVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z);
+	void glVertexAttrib3fv(GLuint indx, const GLfloat* values);
+	void glVertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+	void glVertexAttrib4fv(GLuint indx, const GLfloat* values);
+	void glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr);
+	void glViewport(GLint x, GLint y, GLsizei width, GLsizei height);
+	void glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image);
+	void glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image);
+	void glGetProgramBinaryOES(GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary);
+	void glProgramBinaryOES(GLuint program, GLenum binaryFormat, const GLvoid* binary, GLint length);
+	void* glMapBufferOES(GLenum target, GLenum access);
+	GLboolean glUnmapBufferOES(GLenum target);
+	void glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels);
+	void glTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels);
+	void glCopyTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+	void glCompressedTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data);
+	void glCompressedTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data);
+	void glFramebufferTexture3DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+	void glBindVertexArrayOES(GLuint array);
+	void glDeleteVertexArraysOES(GLsizei n, const GLuint* arrays);
+	void glGenVertexArraysOES(GLsizei n, GLuint* arrays);
+	GLboolean glIsVertexArrayOES(GLuint array);
+	void glDiscardFramebufferEXT(GLenum target, GLsizei numAttachments, const GLenum* attachments);
+	void glMultiDrawArraysEXT(GLenum mode, GLint* first, GLsizei* count, GLsizei primcount);
+	void glMultiDrawElementsEXT(GLenum mode, const GLsizei* count, GLenum type, const GLvoid** indices, GLsizei primcount);
+	void glGetPerfMonitorGroupsAMD(GLint* numGroups, GLsizei groupsSize, GLuint* groups);
+	void glGetPerfMonitorCountersAMD(GLuint group, GLint* numCounters, GLint* maxActiveCounters, GLsizei counterSize, GLuint* counters);
+	void glGetPerfMonitorGroupStringAMD(GLuint group, GLsizei bufSize, GLsizei* length, GLchar* groupString);
+	void glGetPerfMonitorCounterStringAMD(GLuint group, GLuint counter, GLsizei bufSize, GLsizei* length, GLchar* counterString);
+	void glGetPerfMonitorCounterInfoAMD(GLuint group, GLuint counter, GLenum pname, GLvoid* data);
+	void glGenPerfMonitorsAMD(GLsizei n, GLuint* monitors);
+	void glDeletePerfMonitorsAMD(GLsizei n, GLuint* monitors);
+	void glSelectPerfMonitorCountersAMD(GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint* countersList);
+	void glBeginPerfMonitorAMD(GLuint monitor);
+	void glEndPerfMonitorAMD(GLuint monitor);
+	void glGetPerfMonitorCounterDataAMD(GLuint monitor, GLenum pname, GLsizei dataSize, GLuint* data, GLint* bytesWritten);
+	void glRenderbufferStorageMultisampleIMG(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+	void glFramebufferTexture2DMultisampleIMG(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples);
+	void glDeleteFencesNV(GLsizei n, const GLuint* fences);
+	void glGenFencesNV(GLsizei n, GLuint* fences);
+	GLboolean glIsFenceNV(GLuint fence);
+	GLboolean glTestFenceNV(GLuint fence);
+	void glGetFenceivNV(GLuint fence, GLenum pname, GLint* params);
+	void glFinishFenceNV(GLuint fence);
+	void glSetFenceNV(GLuint fence, GLenum condition);
+	void glCoverageMaskNV(GLboolean mask);
+	void glCoverageOperationNV(GLenum operation);
+	void glGetDriverControlsQCOM(GLint* num, GLsizei size, GLuint* driverControls);
+	void glGetDriverControlStringQCOM(GLuint driverControl, GLsizei bufSize, GLsizei* length, GLchar* driverControlString);
+	void glEnableDriverControlQCOM(GLuint driverControl);
+	void glDisableDriverControlQCOM(GLuint driverControl);
+	void glExtGetTexturesQCOM(GLuint* textures, GLint maxTextures, GLint* numTextures);
+	void glExtGetBuffersQCOM(GLuint* buffers, GLint maxBuffers, GLint* numBuffers);
+	void glExtGetRenderbuffersQCOM(GLuint* renderbuffers, GLint maxRenderbuffers, GLint* numRenderbuffers);
+	void glExtGetFramebuffersQCOM(GLuint* framebuffers, GLint maxFramebuffers, GLint* numFramebuffers);
+	void glExtGetTexLevelParameterivQCOM(GLuint texture, GLenum face, GLint level, GLenum pname, GLint* params);
+	void glExtTexObjectStateOverrideiQCOM(GLenum target, GLenum pname, GLint param);
+	void glExtGetTexSubImageQCOM(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid* texels);
+	void glExtGetBufferPointervQCOM(GLenum target, GLvoidptr* params);
+	void glExtGetShadersQCOM(GLuint* shaders, GLint maxShaders, GLint* numShaders);
+	void glExtGetProgramsQCOM(GLuint* programs, GLint maxPrograms, GLint* numPrograms);
+	GLboolean glExtIsProgramBinaryQCOM(GLuint program);
+	void glExtGetProgramBinarySourceQCOM(GLuint program, GLenum shadertype, GLchar* source, GLint* length);
+	void glStartTilingQCOM(GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask);
+	void glEndTilingQCOM(GLbitfield preserveMask);
+	void glVertexAttribPointerData(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, void* data, GLuint datalen);
+	void glVertexAttribPointerOffset(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint offset);
+	void glDrawElementsOffset(GLenum mode, GLsizei count, GLenum type, GLuint offset);
+	void glDrawElementsData(GLenum mode, GLsizei count, GLenum type, void* data, GLuint datalen);
+	void glGetCompressedTextureFormats(int count, GLint* formats);
+	void glShaderString(GLuint shader, const GLchar* string, GLsizei len);
+	int glFinishRoundTrip();
+};
+
+#endif
+#ifndef GET_CONTEXT
+static gl2_client_context_t::CONTEXT_ACCESSOR_TYPE *getCurrentContext = NULL;
+void gl2_client_context_t::setContextAccessor(CONTEXT_ACCESSOR_TYPE *f) { getCurrentContext = f; }
+#define GET_CONTEXT gl2_client_context_t * ctx = getCurrentContext()
+#endif
+
+void glActiveTexture(GLenum texture)
+{
+	GET_CONTEXT;
+	 ctx->glActiveTexture(ctx, texture);
+}
+
+void glAttachShader(GLuint program, GLuint shader)
+{
+	GET_CONTEXT;
+	 ctx->glAttachShader(ctx, program, shader);
+}
+
+void glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
+{
+	GET_CONTEXT;
+	 ctx->glBindAttribLocation(ctx, program, index, name);
+}
+
+void glBindBuffer(GLenum target, GLuint buffer)
+{
+	GET_CONTEXT;
+	 ctx->glBindBuffer(ctx, target, buffer);
+}
+
+void glBindFramebuffer(GLenum target, GLuint framebuffer)
+{
+	GET_CONTEXT;
+	 ctx->glBindFramebuffer(ctx, target, framebuffer);
+}
+
+void glBindRenderbuffer(GLenum target, GLuint renderbuffer)
+{
+	GET_CONTEXT;
+	 ctx->glBindRenderbuffer(ctx, target, renderbuffer);
+}
+
+void glBindTexture(GLenum target, GLuint texture)
+{
+	GET_CONTEXT;
+	 ctx->glBindTexture(ctx, target, texture);
+}
+
+void glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+	GET_CONTEXT;
+	 ctx->glBlendColor(ctx, red, green, blue, alpha);
+}
+
+void glBlendEquation(GLenum mode)
+{
+	GET_CONTEXT;
+	 ctx->glBlendEquation(ctx, mode);
+}
+
+void glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
+{
+	GET_CONTEXT;
+	 ctx->glBlendEquationSeparate(ctx, modeRGB, modeAlpha);
+}
+
+void glBlendFunc(GLenum sfactor, GLenum dfactor)
+{
+	GET_CONTEXT;
+	 ctx->glBlendFunc(ctx, sfactor, dfactor);
+}
+
+void glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+{
+	GET_CONTEXT;
+	 ctx->glBlendFuncSeparate(ctx, srcRGB, dstRGB, srcAlpha, dstAlpha);
+}
+
+void glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
+{
+	GET_CONTEXT;
+	 ctx->glBufferData(ctx, target, size, data, usage);
+}
+
+void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
+{
+	GET_CONTEXT;
+	 ctx->glBufferSubData(ctx, target, offset, size, data);
+}
+
+GLenum glCheckFramebufferStatus(GLenum target)
+{
+	GET_CONTEXT;
+	 return ctx->glCheckFramebufferStatus(ctx, target);
+}
+
+void glClear(GLbitfield mask)
+{
+	GET_CONTEXT;
+	 ctx->glClear(ctx, mask);
+}
+
+void glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+	GET_CONTEXT;
+	 ctx->glClearColor(ctx, red, green, blue, alpha);
+}
+
+void glClearDepthf(GLclampf depth)
+{
+	GET_CONTEXT;
+	 ctx->glClearDepthf(ctx, depth);
+}
+
+void glClearStencil(GLint s)
+{
+	GET_CONTEXT;
+	 ctx->glClearStencil(ctx, s);
+}
+
+void glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
+{
+	GET_CONTEXT;
+	 ctx->glColorMask(ctx, red, green, blue, alpha);
+}
+
+void glCompileShader(GLuint shader)
+{
+	GET_CONTEXT;
+	 ctx->glCompileShader(ctx, shader);
+}
+
+void glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data)
+{
+	GET_CONTEXT;
+	 ctx->glCompressedTexImage2D(ctx, target, level, internalformat, width, height, border, imageSize, data);
+}
+
+void glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data)
+{
+	GET_CONTEXT;
+	 ctx->glCompressedTexSubImage2D(ctx, target, level, xoffset, yoffset, width, height, format, imageSize, data);
+}
+
+void glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
+{
+	GET_CONTEXT;
+	 ctx->glCopyTexImage2D(ctx, target, level, internalformat, x, y, width, height, border);
+}
+
+void glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+{
+	GET_CONTEXT;
+	 ctx->glCopyTexSubImage2D(ctx, target, level, xoffset, yoffset, x, y, width, height);
+}
+
+GLuint glCreateProgram()
+{
+	GET_CONTEXT;
+	 return ctx->glCreateProgram(ctx);
+}
+
+GLuint glCreateShader(GLenum type)
+{
+	GET_CONTEXT;
+	 return ctx->glCreateShader(ctx, type);
+}
+
+void glCullFace(GLenum mode)
+{
+	GET_CONTEXT;
+	 ctx->glCullFace(ctx, mode);
+}
+
+void glDeleteBuffers(GLsizei n, const GLuint* buffers)
+{
+	GET_CONTEXT;
+	 if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
+	 ctx->glDeleteBuffers(ctx, n, buffers);
+}
+
+void glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
+{
+	GET_CONTEXT;
+	 if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
+	 ctx->glDeleteFramebuffers(ctx, n, framebuffers);
+}
+
+void glDeleteProgram(GLuint program)
+{
+	GET_CONTEXT;
+	 ctx->glDeleteProgram(ctx, program);
+}
+
+void glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
+{
+	GET_CONTEXT;
+	 if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
+	 ctx->glDeleteRenderbuffers(ctx, n, renderbuffers);
+}
+
+void glDeleteShader(GLuint shader)
+{
+	GET_CONTEXT;
+	 ctx->glDeleteShader(ctx, shader);
+}
+
+void glDeleteTextures(GLsizei n, const GLuint* textures)
+{
+	GET_CONTEXT;
+	 if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
+	 ctx->glDeleteTextures(ctx, n, textures);
+}
+
+void glDepthFunc(GLenum func)
+{
+	GET_CONTEXT;
+	 ctx->glDepthFunc(ctx, func);
+}
+
+void glDepthMask(GLboolean flag)
+{
+	GET_CONTEXT;
+	 ctx->glDepthMask(ctx, flag);
+}
+
+void glDepthRangef(GLclampf zNear, GLclampf zFar)
+{
+	GET_CONTEXT;
+	 ctx->glDepthRangef(ctx, zNear, zFar);
+}
+
+void glDetachShader(GLuint program, GLuint shader)
+{
+	GET_CONTEXT;
+	 ctx->glDetachShader(ctx, program, shader);
+}
+
+void glDisable(GLenum cap)
+{
+	GET_CONTEXT;
+	 ctx->glDisable(ctx, cap);
+}
+
+void glDisableVertexAttribArray(GLuint index)
+{
+	GET_CONTEXT;
+	 ctx->glDisableVertexAttribArray(ctx, index);
+}
+
+void glDrawArrays(GLenum mode, GLint first, GLsizei count)
+{
+	GET_CONTEXT;
+	 ctx->glDrawArrays(ctx, mode, first, count);
+}
+
+void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
+{
+	GET_CONTEXT;
+	 ctx->glDrawElements(ctx, mode, count, type, indices);
+}
+
+void glEnable(GLenum cap)
+{
+	GET_CONTEXT;
+	 ctx->glEnable(ctx, cap);
+}
+
+void glEnableVertexAttribArray(GLuint index)
+{
+	GET_CONTEXT;
+	 ctx->glEnableVertexAttribArray(ctx, index);
+}
+
+void glFinish()
+{
+	GET_CONTEXT;
+	 ctx->glFinish(ctx);
+}
+
+void glFlush()
+{
+	GET_CONTEXT;
+	 ctx->glFlush(ctx);
+}
+
+void glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
+{
+	GET_CONTEXT;
+	 ctx->glFramebufferRenderbuffer(ctx, target, attachment, renderbuffertarget, renderbuffer);
+}
+
+void glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
+{
+	GET_CONTEXT;
+	 ctx->glFramebufferTexture2D(ctx, target, attachment, textarget, texture, level);
+}
+
+void glFrontFace(GLenum mode)
+{
+	GET_CONTEXT;
+	 ctx->glFrontFace(ctx, mode);
+}
+
+void glGenBuffers(GLsizei n, GLuint* buffers)
+{
+	GET_CONTEXT;
+	 if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
+	 ctx->glGenBuffers(ctx, n, buffers);
+}
+
+void glGenerateMipmap(GLenum target)
+{
+	GET_CONTEXT;
+	 ctx->glGenerateMipmap(ctx, target);
+}
+
+void glGenFramebuffers(GLsizei n, GLuint* framebuffers)
+{
+	GET_CONTEXT;
+	 if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
+	 ctx->glGenFramebuffers(ctx, n, framebuffers);
+}
+
+void glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
+{
+	GET_CONTEXT;
+	 if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
+	 ctx->glGenRenderbuffers(ctx, n, renderbuffers);
+}
+
+void glGenTextures(GLsizei n, GLuint* textures)
+{
+	GET_CONTEXT;
+	 if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
+	 ctx->glGenTextures(ctx, n, textures);
+}
+
+void glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
+{
+	GET_CONTEXT;
+	 ctx->glGetActiveAttrib(ctx, program, index, bufsize, length, size, type, name);
+}
+
+void glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
+{
+	GET_CONTEXT;
+	 ctx->glGetActiveUniform(ctx, program, index, bufsize, length, size, type, name);
+}
+
+void glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
+{
+	GET_CONTEXT;
+	 ctx->glGetAttachedShaders(ctx, program, maxcount, count, shaders);
+}
+
+int glGetAttribLocation(GLuint program, const GLchar* name)
+{
+	GET_CONTEXT;
+	 return ctx->glGetAttribLocation(ctx, program, name);
+}
+
+void glGetBooleanv(GLenum pname, GLboolean* params)
+{
+	GET_CONTEXT;
+	 ctx->glGetBooleanv(ctx, pname, params);
+}
+
+void glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+	GET_CONTEXT;
+	 ctx->glGetBufferParameteriv(ctx, target, pname, params);
+}
+
+GLenum glGetError()
+{
+	GET_CONTEXT;
+	 return ctx->glGetError(ctx);
+}
+
+void glGetFloatv(GLenum pname, GLfloat* params)
+{
+	GET_CONTEXT;
+	 ctx->glGetFloatv(ctx, pname, params);
+}
+
+void glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
+{
+	GET_CONTEXT;
+	 ctx->glGetFramebufferAttachmentParameteriv(ctx, target, attachment, pname, params);
+}
+
+void glGetIntegerv(GLenum pname, GLint* params)
+{
+	GET_CONTEXT;
+	 ctx->glGetIntegerv(ctx, pname, params);
+}
+
+void glGetProgramiv(GLuint program, GLenum pname, GLint* params)
+{
+	GET_CONTEXT;
+	 ctx->glGetProgramiv(ctx, program, pname, params);
+}
+
+void glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
+{
+	GET_CONTEXT;
+	 ctx->glGetProgramInfoLog(ctx, program, bufsize, length, infolog);
+}
+
+void glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+	GET_CONTEXT;
+	 ctx->glGetRenderbufferParameteriv(ctx, target, pname, params);
+}
+
+void glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
+{
+	GET_CONTEXT;
+	 ctx->glGetShaderiv(ctx, shader, pname, params);
+}
+
+void glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
+{
+	GET_CONTEXT;
+	 ctx->glGetShaderInfoLog(ctx, shader, bufsize, length, infolog);
+}
+
+void glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
+{
+	GET_CONTEXT;
+	 ctx->glGetShaderPrecisionFormat(ctx, shadertype, precisiontype, range, precision);
+}
+
+void glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
+{
+	GET_CONTEXT;
+	 ctx->glGetShaderSource(ctx, shader, bufsize, length, source);
+}
+
+const GLubyte* glGetString(GLenum name)
+{
+	GET_CONTEXT;
+	 return ctx->glGetString(ctx, name);
+}
+
+void glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
+{
+	GET_CONTEXT;
+	 ctx->glGetTexParameterfv(ctx, target, pname, params);
+}
+
+void glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+	GET_CONTEXT;
+	 ctx->glGetTexParameteriv(ctx, target, pname, params);
+}
+
+void glGetUniformfv(GLuint program, GLint location, GLfloat* params)
+{
+	GET_CONTEXT;
+	 ctx->glGetUniformfv(ctx, program, location, params);
+}
+
+void glGetUniformiv(GLuint program, GLint location, GLint* params)
+{
+	GET_CONTEXT;
+	 ctx->glGetUniformiv(ctx, program, location, params);
+}
+
+int glGetUniformLocation(GLuint program, const GLchar* name)
+{
+	GET_CONTEXT;
+	 return ctx->glGetUniformLocation(ctx, program, name);
+}
+
+void glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
+{
+	GET_CONTEXT;
+	 ctx->glGetVertexAttribfv(ctx, index, pname, params);
+}
+
+void glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
+{
+	GET_CONTEXT;
+	 ctx->glGetVertexAttribiv(ctx, index, pname, params);
+}
+
+void glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
+{
+	GET_CONTEXT;
+	 ctx->glGetVertexAttribPointerv(ctx, index, pname, pointer);
+}
+
+void glHint(GLenum target, GLenum mode)
+{
+	GET_CONTEXT;
+	 ctx->glHint(ctx, target, mode);
+}
+
+GLboolean glIsBuffer(GLuint buffer)
+{
+	GET_CONTEXT;
+	 return ctx->glIsBuffer(ctx, buffer);
+}
+
+GLboolean glIsEnabled(GLenum cap)
+{
+	GET_CONTEXT;
+	 return ctx->glIsEnabled(ctx, cap);
+}
+
+GLboolean glIsFramebuffer(GLuint framebuffer)
+{
+	GET_CONTEXT;
+	 return ctx->glIsFramebuffer(ctx, framebuffer);
+}
+
+GLboolean glIsProgram(GLuint program)
+{
+	GET_CONTEXT;
+	 return ctx->glIsProgram(ctx, program);
+}
+
+GLboolean glIsRenderbuffer(GLuint renderbuffer)
+{
+	GET_CONTEXT;
+	 return ctx->glIsRenderbuffer(ctx, renderbuffer);
+}
+
+GLboolean glIsShader(GLuint shader)
+{
+	GET_CONTEXT;
+	 return ctx->glIsShader(ctx, shader);
+}
+
+GLboolean glIsTexture(GLuint texture)
+{
+	GET_CONTEXT;
+	 return ctx->glIsTexture(ctx, texture);
+}
+
+void glLineWidth(GLfloat width)
+{
+	GET_CONTEXT;
+	 ctx->glLineWidth(ctx, width);
+}
+
+void glLinkProgram(GLuint program)
+{
+	GET_CONTEXT;
+	 ctx->glLinkProgram(ctx, program);
+}
+
+void glPixelStorei(GLenum pname, GLint param)
+{
+	GET_CONTEXT;
+	 ctx->glPixelStorei(ctx, pname, param);
+}
+
+void glPolygonOffset(GLfloat factor, GLfloat units)
+{
+	GET_CONTEXT;
+	 ctx->glPolygonOffset(ctx, factor, units);
+}
+
+void glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
+{
+	GET_CONTEXT;
+	 ctx->glReadPixels(ctx, x, y, width, height, format, type, pixels);
+}
+
+void glReleaseShaderCompiler()
+{
+	GET_CONTEXT;
+	 ctx->glReleaseShaderCompiler(ctx);
+}
+
+void glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+{
+	GET_CONTEXT;
+	 ctx->glRenderbufferStorage(ctx, target, internalformat, width, height);
+}
+
+void glSampleCoverage(GLclampf value, GLboolean invert)
+{
+	GET_CONTEXT;
+	 ctx->glSampleCoverage(ctx, value, invert);
+}
+
+void glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+	GET_CONTEXT;
+	 ctx->glScissor(ctx, x, y, width, height);
+}
+
+void glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
+{
+	GET_CONTEXT;
+	 ctx->glShaderBinary(ctx, n, shaders, binaryformat, binary, length);
+}
+
+void glShaderSource(GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length)
+{
+	GET_CONTEXT;
+	 ctx->glShaderSource(ctx, shader, count, string, length);
+}
+
+void glStencilFunc(GLenum func, GLint ref, GLuint mask)
+{
+	GET_CONTEXT;
+	 ctx->glStencilFunc(ctx, func, ref, mask);
+}
+
+void glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
+{
+	GET_CONTEXT;
+	 ctx->glStencilFuncSeparate(ctx, face, func, ref, mask);
+}
+
+void glStencilMask(GLuint mask)
+{
+	GET_CONTEXT;
+	 ctx->glStencilMask(ctx, mask);
+}
+
+void glStencilMaskSeparate(GLenum face, GLuint mask)
+{
+	GET_CONTEXT;
+	 ctx->glStencilMaskSeparate(ctx, face, mask);
+}
+
+void glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
+{
+	GET_CONTEXT;
+	 ctx->glStencilOp(ctx, fail, zfail, zpass);
+}
+
+void glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
+{
+	GET_CONTEXT;
+	 ctx->glStencilOpSeparate(ctx, face, fail, zfail, zpass);
+}
+
+void glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels)
+{
+	GET_CONTEXT;
+	 ctx->glTexImage2D(ctx, target, level, internalformat, width, height, border, format, type, pixels);
+}
+
+void glTexParameterf(GLenum target, GLenum pname, GLfloat param)
+{
+	GET_CONTEXT;
+	 ctx->glTexParameterf(ctx, target, pname, param);
+}
+
+void glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
+{
+	GET_CONTEXT;
+	 ctx->glTexParameterfv(ctx, target, pname, params);
+}
+
+void glTexParameteri(GLenum target, GLenum pname, GLint param)
+{
+	GET_CONTEXT;
+	 ctx->glTexParameteri(ctx, target, pname, param);
+}
+
+void glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
+{
+	GET_CONTEXT;
+	 ctx->glTexParameteriv(ctx, target, pname, params);
+}
+
+void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels)
+{
+	GET_CONTEXT;
+	 ctx->glTexSubImage2D(ctx, target, level, xoffset, yoffset, width, height, format, type, pixels);
+}
+
+void glUniform1f(GLint location, GLfloat x)
+{
+	GET_CONTEXT;
+	 ctx->glUniform1f(ctx, location, x);
+}
+
+void glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
+{
+	GET_CONTEXT;
+	 ctx->glUniform1fv(ctx, location, count, v);
+}
+
+void glUniform1i(GLint location, GLint x)
+{
+	GET_CONTEXT;
+	 ctx->glUniform1i(ctx, location, x);
+}
+
+void glUniform1iv(GLint location, GLsizei count, const GLint* v)
+{
+	GET_CONTEXT;
+	 ctx->glUniform1iv(ctx, location, count, v);
+}
+
+void glUniform2f(GLint location, GLfloat x, GLfloat y)
+{
+	GET_CONTEXT;
+	 ctx->glUniform2f(ctx, location, x, y);
+}
+
+void glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
+{
+	GET_CONTEXT;
+	 ctx->glUniform2fv(ctx, location, count, v);
+}
+
+void glUniform2i(GLint location, GLint x, GLint y)
+{
+	GET_CONTEXT;
+	 ctx->glUniform2i(ctx, location, x, y);
+}
+
+void glUniform2iv(GLint location, GLsizei count, const GLint* v)
+{
+	GET_CONTEXT;
+	 ctx->glUniform2iv(ctx, location, count, v);
+}
+
+void glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
+{
+	GET_CONTEXT;
+	 ctx->glUniform3f(ctx, location, x, y, z);
+}
+
+void glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
+{
+	GET_CONTEXT;
+	 ctx->glUniform3fv(ctx, location, count, v);
+}
+
+void glUniform3i(GLint location, GLint x, GLint y, GLint z)
+{
+	GET_CONTEXT;
+	 ctx->glUniform3i(ctx, location, x, y, z);
+}
+
+void glUniform3iv(GLint location, GLsizei count, const GLint* v)
+{
+	GET_CONTEXT;
+	 ctx->glUniform3iv(ctx, location, count, v);
+}
+
+void glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+	GET_CONTEXT;
+	 ctx->glUniform4f(ctx, location, x, y, z, w);
+}
+
+void glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
+{
+	GET_CONTEXT;
+	 ctx->glUniform4fv(ctx, location, count, v);
+}
+
+void glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
+{
+	GET_CONTEXT;
+	 ctx->glUniform4i(ctx, location, x, y, z, w);
+}
+
+void glUniform4iv(GLint location, GLsizei count, const GLint* v)
+{
+	GET_CONTEXT;
+	 ctx->glUniform4iv(ctx, location, count, v);
+}
+
+void glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+	GET_CONTEXT;
+	 ctx->glUniformMatrix2fv(ctx, location, count, transpose, value);
+}
+
+void glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+	GET_CONTEXT;
+	 ctx->glUniformMatrix3fv(ctx, location, count, transpose, value);
+}
+
+void glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+	GET_CONTEXT;
+	 ctx->glUniformMatrix4fv(ctx, location, count, transpose, value);
+}
+
+void glUseProgram(GLuint program)
+{
+	GET_CONTEXT;
+	 ctx->glUseProgram(ctx, program);
+}
+
+void glValidateProgram(GLuint program)
+{
+	GET_CONTEXT;
+	 ctx->glValidateProgram(ctx, program);
+}
+
+void glVertexAttrib1f(GLuint indx, GLfloat x)
+{
+	GET_CONTEXT;
+	 ctx->glVertexAttrib1f(ctx, indx, x);
+}
+
+void glVertexAttrib1fv(GLuint indx, const GLfloat* values)
+{
+	GET_CONTEXT;
+	 ctx->glVertexAttrib1fv(ctx, indx, values);
+}
+
+void glVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y)
+{
+	GET_CONTEXT;
+	 ctx->glVertexAttrib2f(ctx, indx, x, y);
+}
+
+void glVertexAttrib2fv(GLuint indx, const GLfloat* values)
+{
+	GET_CONTEXT;
+	 ctx->glVertexAttrib2fv(ctx, indx, values);
+}
+
+void glVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z)
+{
+	GET_CONTEXT;
+	 ctx->glVertexAttrib3f(ctx, indx, x, y, z);
+}
+
+void glVertexAttrib3fv(GLuint indx, const GLfloat* values)
+{
+	GET_CONTEXT;
+	 ctx->glVertexAttrib3fv(ctx, indx, values);
+}
+
+void glVertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+	GET_CONTEXT;
+	 ctx->glVertexAttrib4f(ctx, indx, x, y, z, w);
+}
+
+void glVertexAttrib4fv(GLuint indx, const GLfloat* values)
+{
+	GET_CONTEXT;
+	 ctx->glVertexAttrib4fv(ctx, indx, values);
+}
+
+void glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
+{
+	GET_CONTEXT;
+	 ctx->glVertexAttribPointer(ctx, indx, size, type, normalized, stride, ptr);
+}
+
+void glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+	GET_CONTEXT;
+	 ctx->glViewport(ctx, x, y, width, height);
+}
+
+void glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
+{
+	GET_CONTEXT;
+	 ctx->glEGLImageTargetTexture2DOES(ctx, target, image);
+}
+
+void glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
+{
+	GET_CONTEXT;
+	 ctx->glEGLImageTargetRenderbufferStorageOES(ctx, target, image);
+}
+
+void glGetProgramBinaryOES(GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary)
+{
+	GET_CONTEXT;
+	 ctx->glGetProgramBinaryOES(ctx, program, bufSize, length, binaryFormat, binary);
+}
+
+void glProgramBinaryOES(GLuint program, GLenum binaryFormat, const GLvoid* binary, GLint length)
+{
+	GET_CONTEXT;
+	 ctx->glProgramBinaryOES(ctx, program, binaryFormat, binary, length);
+}
+
+void* glMapBufferOES(GLenum target, GLenum access)
+{
+	GET_CONTEXT;
+	 return ctx->glMapBufferOES(ctx, target, access);
+}
+
+GLboolean glUnmapBufferOES(GLenum target)
+{
+	GET_CONTEXT;
+	 return ctx->glUnmapBufferOES(ctx, target);
+}
+
+void glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels)
+{
+	GET_CONTEXT;
+	 ctx->glTexImage3DOES(ctx, target, level, internalformat, width, height, depth, border, format, type, pixels);
+}
+
+void glTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels)
+{
+	GET_CONTEXT;
+	 ctx->glTexSubImage3DOES(ctx, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
+}
+
+void glCopyTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+{
+	GET_CONTEXT;
+	 ctx->glCopyTexSubImage3DOES(ctx, target, level, xoffset, yoffset, zoffset, x, y, width, height);
+}
+
+void glCompressedTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data)
+{
+	GET_CONTEXT;
+	 ctx->glCompressedTexImage3DOES(ctx, target, level, internalformat, width, height, depth, border, imageSize, data);
+}
+
+void glCompressedTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data)
+{
+	GET_CONTEXT;
+	 ctx->glCompressedTexSubImage3DOES(ctx, target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
+}
+
+void glFramebufferTexture3DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)
+{
+	GET_CONTEXT;
+	 ctx->glFramebufferTexture3DOES(ctx, target, attachment, textarget, texture, level, zoffset);
+}
+
+void glBindVertexArrayOES(GLuint array)
+{
+	GET_CONTEXT;
+	 ctx->glBindVertexArrayOES(ctx, array);
+}
+
+void glDeleteVertexArraysOES(GLsizei n, const GLuint* arrays)
+{
+	GET_CONTEXT;
+	 if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
+	 ctx->glDeleteVertexArraysOES(ctx, n, arrays);
+}
+
+void glGenVertexArraysOES(GLsizei n, GLuint* arrays)
+{
+	GET_CONTEXT;
+	 if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
+	 ctx->glGenVertexArraysOES(ctx, n, arrays);
+}
+
+GLboolean glIsVertexArrayOES(GLuint array)
+{
+	GET_CONTEXT;
+	 return ctx->glIsVertexArrayOES(ctx, array);
+}
+
+void glDiscardFramebufferEXT(GLenum target, GLsizei numAttachments, const GLenum* attachments)
+{
+	GET_CONTEXT;
+	 ctx->glDiscardFramebufferEXT(ctx, target, numAttachments, attachments);
+}
+
+void glMultiDrawArraysEXT(GLenum mode, GLint* first, GLsizei* count, GLsizei primcount)
+{
+	GET_CONTEXT;
+	 ctx->glMultiDrawArraysEXT(ctx, mode, first, count, primcount);
+}
+
+void glMultiDrawElementsEXT(GLenum mode, const GLsizei* count, GLenum type, const GLvoid** indices, GLsizei primcount)
+{
+	GET_CONTEXT;
+	 ctx->glMultiDrawElementsEXT(ctx, mode, count, type, indices, primcount);
+}
+
+void glGetPerfMonitorGroupsAMD(GLint* numGroups, GLsizei groupsSize, GLuint* groups)
+{
+	GET_CONTEXT;
+	 ctx->glGetPerfMonitorGroupsAMD(ctx, numGroups, groupsSize, groups);
+}
+
+void glGetPerfMonitorCountersAMD(GLuint group, GLint* numCounters, GLint* maxActiveCounters, GLsizei counterSize, GLuint* counters)
+{
+	GET_CONTEXT;
+	 ctx->glGetPerfMonitorCountersAMD(ctx, group, numCounters, maxActiveCounters, counterSize, counters);
+}
+
+void glGetPerfMonitorGroupStringAMD(GLuint group, GLsizei bufSize, GLsizei* length, GLchar* groupString)
+{
+	GET_CONTEXT;
+	 ctx->glGetPerfMonitorGroupStringAMD(ctx, group, bufSize, length, groupString);
+}
+
+void glGetPerfMonitorCounterStringAMD(GLuint group, GLuint counter, GLsizei bufSize, GLsizei* length, GLchar* counterString)
+{
+	GET_CONTEXT;
+	 ctx->glGetPerfMonitorCounterStringAMD(ctx, group, counter, bufSize, length, counterString);
+}
+
+void glGetPerfMonitorCounterInfoAMD(GLuint group, GLuint counter, GLenum pname, GLvoid* data)
+{
+	GET_CONTEXT;
+	 ctx->glGetPerfMonitorCounterInfoAMD(ctx, group, counter, pname, data);
+}
+
+void glGenPerfMonitorsAMD(GLsizei n, GLuint* monitors)
+{
+	GET_CONTEXT;
+	 ctx->glGenPerfMonitorsAMD(ctx, n, monitors);
+}
+
+void glDeletePerfMonitorsAMD(GLsizei n, GLuint* monitors)
+{
+	GET_CONTEXT;
+	 ctx->glDeletePerfMonitorsAMD(ctx, n, monitors);
+}
+
+void glSelectPerfMonitorCountersAMD(GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint* countersList)
+{
+	GET_CONTEXT;
+	 ctx->glSelectPerfMonitorCountersAMD(ctx, monitor, enable, group, numCounters, countersList);
+}
+
+void glBeginPerfMonitorAMD(GLuint monitor)
+{
+	GET_CONTEXT;
+	 ctx->glBeginPerfMonitorAMD(ctx, monitor);
+}
+
+void glEndPerfMonitorAMD(GLuint monitor)
+{
+	GET_CONTEXT;
+	 ctx->glEndPerfMonitorAMD(ctx, monitor);
+}
+
+void glGetPerfMonitorCounterDataAMD(GLuint monitor, GLenum pname, GLsizei dataSize, GLuint* data, GLint* bytesWritten)
+{
+	GET_CONTEXT;
+	 ctx->glGetPerfMonitorCounterDataAMD(ctx, monitor, pname, dataSize, data, bytesWritten);
+}
+
+void glRenderbufferStorageMultisampleIMG(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
+{
+	GET_CONTEXT;
+	 ctx->glRenderbufferStorageMultisampleIMG(ctx, target, samples, internalformat, width, height);
+}
+
+void glFramebufferTexture2DMultisampleIMG(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples)
+{
+	GET_CONTEXT;
+	 ctx->glFramebufferTexture2DMultisampleIMG(ctx, target, attachment, textarget, texture, level, samples);
+}
+
+void glDeleteFencesNV(GLsizei n, const GLuint* fences)
+{
+	GET_CONTEXT;
+	 ctx->glDeleteFencesNV(ctx, n, fences);
+}
+
+void glGenFencesNV(GLsizei n, GLuint* fences)
+{
+	GET_CONTEXT;
+	 ctx->glGenFencesNV(ctx, n, fences);
+}
+
+GLboolean glIsFenceNV(GLuint fence)
+{
+	GET_CONTEXT;
+	 return ctx->glIsFenceNV(ctx, fence);
+}
+
+GLboolean glTestFenceNV(GLuint fence)
+{
+	GET_CONTEXT;
+	 return ctx->glTestFenceNV(ctx, fence);
+}
+
+void glGetFenceivNV(GLuint fence, GLenum pname, GLint* params)
+{
+	GET_CONTEXT;
+	 ctx->glGetFenceivNV(ctx, fence, pname, params);
+}
+
+void glFinishFenceNV(GLuint fence)
+{
+	GET_CONTEXT;
+	 ctx->glFinishFenceNV(ctx, fence);
+}
+
+void glSetFenceNV(GLuint fence, GLenum condition)
+{
+	GET_CONTEXT;
+	 ctx->glSetFenceNV(ctx, fence, condition);
+}
+
+void glCoverageMaskNV(GLboolean mask)
+{
+	GET_CONTEXT;
+	 ctx->glCoverageMaskNV(ctx, mask);
+}
+
+void glCoverageOperationNV(GLenum operation)
+{
+	GET_CONTEXT;
+	 ctx->glCoverageOperationNV(ctx, operation);
+}
+
+void glGetDriverControlsQCOM(GLint* num, GLsizei size, GLuint* driverControls)
+{
+	GET_CONTEXT;
+	 ctx->glGetDriverControlsQCOM(ctx, num, size, driverControls);
+}
+
+void glGetDriverControlStringQCOM(GLuint driverControl, GLsizei bufSize, GLsizei* length, GLchar* driverControlString)
+{
+	GET_CONTEXT;
+	 ctx->glGetDriverControlStringQCOM(ctx, driverControl, bufSize, length, driverControlString);
+}
+
+void glEnableDriverControlQCOM(GLuint driverControl)
+{
+	GET_CONTEXT;
+	 ctx->glEnableDriverControlQCOM(ctx, driverControl);
+}
+
+void glDisableDriverControlQCOM(GLuint driverControl)
+{
+	GET_CONTEXT;
+	 ctx->glDisableDriverControlQCOM(ctx, driverControl);
+}
+
+void glExtGetTexturesQCOM(GLuint* textures, GLint maxTextures, GLint* numTextures)
+{
+	GET_CONTEXT;
+	 ctx->glExtGetTexturesQCOM(ctx, textures, maxTextures, numTextures);
+}
+
+void glExtGetBuffersQCOM(GLuint* buffers, GLint maxBuffers, GLint* numBuffers)
+{
+	GET_CONTEXT;
+	 ctx->glExtGetBuffersQCOM(ctx, buffers, maxBuffers, numBuffers);
+}
+
+void glExtGetRenderbuffersQCOM(GLuint* renderbuffers, GLint maxRenderbuffers, GLint* numRenderbuffers)
+{
+	GET_CONTEXT;
+	 ctx->glExtGetRenderbuffersQCOM(ctx, renderbuffers, maxRenderbuffers, numRenderbuffers);
+}
+
+void glExtGetFramebuffersQCOM(GLuint* framebuffers, GLint maxFramebuffers, GLint* numFramebuffers)
+{
+	GET_CONTEXT;
+	 ctx->glExtGetFramebuffersQCOM(ctx, framebuffers, maxFramebuffers, numFramebuffers);
+}
+
+void glExtGetTexLevelParameterivQCOM(GLuint texture, GLenum face, GLint level, GLenum pname, GLint* params)
+{
+	GET_CONTEXT;
+	 ctx->glExtGetTexLevelParameterivQCOM(ctx, texture, face, level, pname, params);
+}
+
+void glExtTexObjectStateOverrideiQCOM(GLenum target, GLenum pname, GLint param)
+{
+	GET_CONTEXT;
+	 ctx->glExtTexObjectStateOverrideiQCOM(ctx, target, pname, param);
+}
+
+void glExtGetTexSubImageQCOM(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid* texels)
+{
+	GET_CONTEXT;
+	 ctx->glExtGetTexSubImageQCOM(ctx, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, texels);
+}
+
+void glExtGetBufferPointervQCOM(GLenum target, GLvoidptr* params)
+{
+	GET_CONTEXT;
+	 ctx->glExtGetBufferPointervQCOM(ctx, target, params);
+}
+
+void glExtGetShadersQCOM(GLuint* shaders, GLint maxShaders, GLint* numShaders)
+{
+	GET_CONTEXT;
+	 ctx->glExtGetShadersQCOM(ctx, shaders, maxShaders, numShaders);
+}
+
+void glExtGetProgramsQCOM(GLuint* programs, GLint maxPrograms, GLint* numPrograms)
+{
+	GET_CONTEXT;
+	 ctx->glExtGetProgramsQCOM(ctx, programs, maxPrograms, numPrograms);
+}
+
+GLboolean glExtIsProgramBinaryQCOM(GLuint program)
+{
+	GET_CONTEXT;
+	 return ctx->glExtIsProgramBinaryQCOM(ctx, program);
+}
+
+void glExtGetProgramBinarySourceQCOM(GLuint program, GLenum shadertype, GLchar* source, GLint* length)
+{
+	GET_CONTEXT;
+	 ctx->glExtGetProgramBinarySourceQCOM(ctx, program, shadertype, source, length);
+}
+
+void glStartTilingQCOM(GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask)
+{
+	GET_CONTEXT;
+	 ctx->glStartTilingQCOM(ctx, x, y, width, height, preserveMask);
+}
+
+void glEndTilingQCOM(GLbitfield preserveMask)
+{
+	GET_CONTEXT;
+	 ctx->glEndTilingQCOM(ctx, preserveMask);
+}
+
+void glVertexAttribPointerData(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, void* data, GLuint datalen)
+{
+	GET_CONTEXT;
+	 ctx->glVertexAttribPointerData(ctx, indx, size, type, normalized, stride, data, datalen);
+}
+
+void glVertexAttribPointerOffset(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint offset)
+{
+	GET_CONTEXT;
+	 ctx->glVertexAttribPointerOffset(ctx, indx, size, type, normalized, stride, offset);
+}
+
+void glDrawElementsOffset(GLenum mode, GLsizei count, GLenum type, GLuint offset)
+{
+	GET_CONTEXT;
+	 ctx->glDrawElementsOffset(ctx, mode, count, type, offset);
+}
+
+void glDrawElementsData(GLenum mode, GLsizei count, GLenum type, void* data, GLuint datalen)
+{
+	GET_CONTEXT;
+	 ctx->glDrawElementsData(ctx, mode, count, type, data, datalen);
+}
+
+void glGetCompressedTextureFormats(int count, GLint* formats)
+{
+	GET_CONTEXT;
+	 ctx->glGetCompressedTextureFormats(ctx, count, formats);
+}
+
+void glShaderString(GLuint shader, const GLchar* string, GLsizei len)
+{
+	GET_CONTEXT;
+	 ctx->glShaderString(ctx, shader, string, len);
+}
+
+int glFinishRoundTrip()
+{
+	GET_CONTEXT;
+	 return ctx->glFinishRoundTrip(ctx);
+}
+
diff --git a/opengl/system/GLESv2_enc/gl2_ftable.h b/opengl/system/GLESv2_enc/gl2_ftable.h
new file mode 100644
index 0000000..4cbda78
--- /dev/null
+++ b/opengl/system/GLESv2_enc/gl2_ftable.h
@@ -0,0 +1,216 @@
+// Generated Code - DO NOT EDIT !!
+// generated by 'emugen'
+#ifndef __gl2_client_ftable_t_h
+#define __gl2_client_ftable_t_h
+
+
+static struct _gl2_funcs_by_name {
+	const char *name;
+	void *proc;
+} gl2_funcs_by_name[] = {
+	{"glActiveTexture", (void*)glActiveTexture},
+	{"glAttachShader", (void*)glAttachShader},
+	{"glBindAttribLocation", (void*)glBindAttribLocation},
+	{"glBindBuffer", (void*)glBindBuffer},
+	{"glBindFramebuffer", (void*)glBindFramebuffer},
+	{"glBindRenderbuffer", (void*)glBindRenderbuffer},
+	{"glBindTexture", (void*)glBindTexture},
+	{"glBlendColor", (void*)glBlendColor},
+	{"glBlendEquation", (void*)glBlendEquation},
+	{"glBlendEquationSeparate", (void*)glBlendEquationSeparate},
+	{"glBlendFunc", (void*)glBlendFunc},
+	{"glBlendFuncSeparate", (void*)glBlendFuncSeparate},
+	{"glBufferData", (void*)glBufferData},
+	{"glBufferSubData", (void*)glBufferSubData},
+	{"glCheckFramebufferStatus", (void*)glCheckFramebufferStatus},
+	{"glClear", (void*)glClear},
+	{"glClearColor", (void*)glClearColor},
+	{"glClearDepthf", (void*)glClearDepthf},
+	{"glClearStencil", (void*)glClearStencil},
+	{"glColorMask", (void*)glColorMask},
+	{"glCompileShader", (void*)glCompileShader},
+	{"glCompressedTexImage2D", (void*)glCompressedTexImage2D},
+	{"glCompressedTexSubImage2D", (void*)glCompressedTexSubImage2D},
+	{"glCopyTexImage2D", (void*)glCopyTexImage2D},
+	{"glCopyTexSubImage2D", (void*)glCopyTexSubImage2D},
+	{"glCreateProgram", (void*)glCreateProgram},
+	{"glCreateShader", (void*)glCreateShader},
+	{"glCullFace", (void*)glCullFace},
+	{"glDeleteBuffers", (void*)glDeleteBuffers},
+	{"glDeleteFramebuffers", (void*)glDeleteFramebuffers},
+	{"glDeleteProgram", (void*)glDeleteProgram},
+	{"glDeleteRenderbuffers", (void*)glDeleteRenderbuffers},
+	{"glDeleteShader", (void*)glDeleteShader},
+	{"glDeleteTextures", (void*)glDeleteTextures},
+	{"glDepthFunc", (void*)glDepthFunc},
+	{"glDepthMask", (void*)glDepthMask},
+	{"glDepthRangef", (void*)glDepthRangef},
+	{"glDetachShader", (void*)glDetachShader},
+	{"glDisable", (void*)glDisable},
+	{"glDisableVertexAttribArray", (void*)glDisableVertexAttribArray},
+	{"glDrawArrays", (void*)glDrawArrays},
+	{"glDrawElements", (void*)glDrawElements},
+	{"glEnable", (void*)glEnable},
+	{"glEnableVertexAttribArray", (void*)glEnableVertexAttribArray},
+	{"glFinish", (void*)glFinish},
+	{"glFlush", (void*)glFlush},
+	{"glFramebufferRenderbuffer", (void*)glFramebufferRenderbuffer},
+	{"glFramebufferTexture2D", (void*)glFramebufferTexture2D},
+	{"glFrontFace", (void*)glFrontFace},
+	{"glGenBuffers", (void*)glGenBuffers},
+	{"glGenerateMipmap", (void*)glGenerateMipmap},
+	{"glGenFramebuffers", (void*)glGenFramebuffers},
+	{"glGenRenderbuffers", (void*)glGenRenderbuffers},
+	{"glGenTextures", (void*)glGenTextures},
+	{"glGetActiveAttrib", (void*)glGetActiveAttrib},
+	{"glGetActiveUniform", (void*)glGetActiveUniform},
+	{"glGetAttachedShaders", (void*)glGetAttachedShaders},
+	{"glGetAttribLocation", (void*)glGetAttribLocation},
+	{"glGetBooleanv", (void*)glGetBooleanv},
+	{"glGetBufferParameteriv", (void*)glGetBufferParameteriv},
+	{"glGetError", (void*)glGetError},
+	{"glGetFloatv", (void*)glGetFloatv},
+	{"glGetFramebufferAttachmentParameteriv", (void*)glGetFramebufferAttachmentParameteriv},
+	{"glGetIntegerv", (void*)glGetIntegerv},
+	{"glGetProgramiv", (void*)glGetProgramiv},
+	{"glGetProgramInfoLog", (void*)glGetProgramInfoLog},
+	{"glGetRenderbufferParameteriv", (void*)glGetRenderbufferParameteriv},
+	{"glGetShaderiv", (void*)glGetShaderiv},
+	{"glGetShaderInfoLog", (void*)glGetShaderInfoLog},
+	{"glGetShaderPrecisionFormat", (void*)glGetShaderPrecisionFormat},
+	{"glGetShaderSource", (void*)glGetShaderSource},
+	{"glGetString", (void*)glGetString},
+	{"glGetTexParameterfv", (void*)glGetTexParameterfv},
+	{"glGetTexParameteriv", (void*)glGetTexParameteriv},
+	{"glGetUniformfv", (void*)glGetUniformfv},
+	{"glGetUniformiv", (void*)glGetUniformiv},
+	{"glGetUniformLocation", (void*)glGetUniformLocation},
+	{"glGetVertexAttribfv", (void*)glGetVertexAttribfv},
+	{"glGetVertexAttribiv", (void*)glGetVertexAttribiv},
+	{"glGetVertexAttribPointerv", (void*)glGetVertexAttribPointerv},
+	{"glHint", (void*)glHint},
+	{"glIsBuffer", (void*)glIsBuffer},
+	{"glIsEnabled", (void*)glIsEnabled},
+	{"glIsFramebuffer", (void*)glIsFramebuffer},
+	{"glIsProgram", (void*)glIsProgram},
+	{"glIsRenderbuffer", (void*)glIsRenderbuffer},
+	{"glIsShader", (void*)glIsShader},
+	{"glIsTexture", (void*)glIsTexture},
+	{"glLineWidth", (void*)glLineWidth},
+	{"glLinkProgram", (void*)glLinkProgram},
+	{"glPixelStorei", (void*)glPixelStorei},
+	{"glPolygonOffset", (void*)glPolygonOffset},
+	{"glReadPixels", (void*)glReadPixels},
+	{"glReleaseShaderCompiler", (void*)glReleaseShaderCompiler},
+	{"glRenderbufferStorage", (void*)glRenderbufferStorage},
+	{"glSampleCoverage", (void*)glSampleCoverage},
+	{"glScissor", (void*)glScissor},
+	{"glShaderBinary", (void*)glShaderBinary},
+	{"glShaderSource", (void*)glShaderSource},
+	{"glStencilFunc", (void*)glStencilFunc},
+	{"glStencilFuncSeparate", (void*)glStencilFuncSeparate},
+	{"glStencilMask", (void*)glStencilMask},
+	{"glStencilMaskSeparate", (void*)glStencilMaskSeparate},
+	{"glStencilOp", (void*)glStencilOp},
+	{"glStencilOpSeparate", (void*)glStencilOpSeparate},
+	{"glTexImage2D", (void*)glTexImage2D},
+	{"glTexParameterf", (void*)glTexParameterf},
+	{"glTexParameterfv", (void*)glTexParameterfv},
+	{"glTexParameteri", (void*)glTexParameteri},
+	{"glTexParameteriv", (void*)glTexParameteriv},
+	{"glTexSubImage2D", (void*)glTexSubImage2D},
+	{"glUniform1f", (void*)glUniform1f},
+	{"glUniform1fv", (void*)glUniform1fv},
+	{"glUniform1i", (void*)glUniform1i},
+	{"glUniform1iv", (void*)glUniform1iv},
+	{"glUniform2f", (void*)glUniform2f},
+	{"glUniform2fv", (void*)glUniform2fv},
+	{"glUniform2i", (void*)glUniform2i},
+	{"glUniform2iv", (void*)glUniform2iv},
+	{"glUniform3f", (void*)glUniform3f},
+	{"glUniform3fv", (void*)glUniform3fv},
+	{"glUniform3i", (void*)glUniform3i},
+	{"glUniform3iv", (void*)glUniform3iv},
+	{"glUniform4f", (void*)glUniform4f},
+	{"glUniform4fv", (void*)glUniform4fv},
+	{"glUniform4i", (void*)glUniform4i},
+	{"glUniform4iv", (void*)glUniform4iv},
+	{"glUniformMatrix2fv", (void*)glUniformMatrix2fv},
+	{"glUniformMatrix3fv", (void*)glUniformMatrix3fv},
+	{"glUniformMatrix4fv", (void*)glUniformMatrix4fv},
+	{"glUseProgram", (void*)glUseProgram},
+	{"glValidateProgram", (void*)glValidateProgram},
+	{"glVertexAttrib1f", (void*)glVertexAttrib1f},
+	{"glVertexAttrib1fv", (void*)glVertexAttrib1fv},
+	{"glVertexAttrib2f", (void*)glVertexAttrib2f},
+	{"glVertexAttrib2fv", (void*)glVertexAttrib2fv},
+	{"glVertexAttrib3f", (void*)glVertexAttrib3f},
+	{"glVertexAttrib3fv", (void*)glVertexAttrib3fv},
+	{"glVertexAttrib4f", (void*)glVertexAttrib4f},
+	{"glVertexAttrib4fv", (void*)glVertexAttrib4fv},
+	{"glVertexAttribPointer", (void*)glVertexAttribPointer},
+	{"glViewport", (void*)glViewport},
+	{"glEGLImageTargetTexture2DOES", (void*)glEGLImageTargetTexture2DOES},
+	{"glEGLImageTargetRenderbufferStorageOES", (void*)glEGLImageTargetRenderbufferStorageOES},
+	{"glGetProgramBinaryOES", (void*)glGetProgramBinaryOES},
+	{"glProgramBinaryOES", (void*)glProgramBinaryOES},
+	{"glMapBufferOES", (void*)glMapBufferOES},
+	{"glUnmapBufferOES", (void*)glUnmapBufferOES},
+	{"glTexImage3DOES", (void*)glTexImage3DOES},
+	{"glTexSubImage3DOES", (void*)glTexSubImage3DOES},
+	{"glCopyTexSubImage3DOES", (void*)glCopyTexSubImage3DOES},
+	{"glCompressedTexImage3DOES", (void*)glCompressedTexImage3DOES},
+	{"glCompressedTexSubImage3DOES", (void*)glCompressedTexSubImage3DOES},
+	{"glFramebufferTexture3DOES", (void*)glFramebufferTexture3DOES},
+	{"glBindVertexArrayOES", (void*)glBindVertexArrayOES},
+	{"glDeleteVertexArraysOES", (void*)glDeleteVertexArraysOES},
+	{"glGenVertexArraysOES", (void*)glGenVertexArraysOES},
+	{"glIsVertexArrayOES", (void*)glIsVertexArrayOES},
+	{"glDiscardFramebufferEXT", (void*)glDiscardFramebufferEXT},
+	{"glMultiDrawArraysEXT", (void*)glMultiDrawArraysEXT},
+	{"glMultiDrawElementsEXT", (void*)glMultiDrawElementsEXT},
+	{"glGetPerfMonitorGroupsAMD", (void*)glGetPerfMonitorGroupsAMD},
+	{"glGetPerfMonitorCountersAMD", (void*)glGetPerfMonitorCountersAMD},
+	{"glGetPerfMonitorGroupStringAMD", (void*)glGetPerfMonitorGroupStringAMD},
+	{"glGetPerfMonitorCounterStringAMD", (void*)glGetPerfMonitorCounterStringAMD},
+	{"glGetPerfMonitorCounterInfoAMD", (void*)glGetPerfMonitorCounterInfoAMD},
+	{"glGenPerfMonitorsAMD", (void*)glGenPerfMonitorsAMD},
+	{"glDeletePerfMonitorsAMD", (void*)glDeletePerfMonitorsAMD},
+	{"glSelectPerfMonitorCountersAMD", (void*)glSelectPerfMonitorCountersAMD},
+	{"glBeginPerfMonitorAMD", (void*)glBeginPerfMonitorAMD},
+	{"glEndPerfMonitorAMD", (void*)glEndPerfMonitorAMD},
+	{"glGetPerfMonitorCounterDataAMD", (void*)glGetPerfMonitorCounterDataAMD},
+	{"glRenderbufferStorageMultisampleIMG", (void*)glRenderbufferStorageMultisampleIMG},
+	{"glFramebufferTexture2DMultisampleIMG", (void*)glFramebufferTexture2DMultisampleIMG},
+	{"glDeleteFencesNV", (void*)glDeleteFencesNV},
+	{"glGenFencesNV", (void*)glGenFencesNV},
+	{"glIsFenceNV", (void*)glIsFenceNV},
+	{"glTestFenceNV", (void*)glTestFenceNV},
+	{"glGetFenceivNV", (void*)glGetFenceivNV},
+	{"glFinishFenceNV", (void*)glFinishFenceNV},
+	{"glSetFenceNV", (void*)glSetFenceNV},
+	{"glCoverageMaskNV", (void*)glCoverageMaskNV},
+	{"glCoverageOperationNV", (void*)glCoverageOperationNV},
+	{"glGetDriverControlsQCOM", (void*)glGetDriverControlsQCOM},
+	{"glGetDriverControlStringQCOM", (void*)glGetDriverControlStringQCOM},
+	{"glEnableDriverControlQCOM", (void*)glEnableDriverControlQCOM},
+	{"glDisableDriverControlQCOM", (void*)glDisableDriverControlQCOM},
+	{"glExtGetTexturesQCOM", (void*)glExtGetTexturesQCOM},
+	{"glExtGetBuffersQCOM", (void*)glExtGetBuffersQCOM},
+	{"glExtGetRenderbuffersQCOM", (void*)glExtGetRenderbuffersQCOM},
+	{"glExtGetFramebuffersQCOM", (void*)glExtGetFramebuffersQCOM},
+	{"glExtGetTexLevelParameterivQCOM", (void*)glExtGetTexLevelParameterivQCOM},
+	{"glExtTexObjectStateOverrideiQCOM", (void*)glExtTexObjectStateOverrideiQCOM},
+	{"glExtGetTexSubImageQCOM", (void*)glExtGetTexSubImageQCOM},
+	{"glExtGetBufferPointervQCOM", (void*)glExtGetBufferPointervQCOM},
+	{"glExtGetShadersQCOM", (void*)glExtGetShadersQCOM},
+	{"glExtGetProgramsQCOM", (void*)glExtGetProgramsQCOM},
+	{"glExtIsProgramBinaryQCOM", (void*)glExtIsProgramBinaryQCOM},
+	{"glExtGetProgramBinarySourceQCOM", (void*)glExtGetProgramBinarySourceQCOM},
+	{"glStartTilingQCOM", (void*)glStartTilingQCOM},
+	{"glEndTilingQCOM", (void*)glEndTilingQCOM},
+};
+static int gl2_num_funcs = sizeof(gl2_funcs_by_name) / sizeof(struct _gl2_funcs_by_name);
+
+
+#endif
diff --git a/opengl/system/GLESv2_enc/gl2_opcodes.h b/opengl/system/GLESv2_enc/gl2_opcodes.h
new file mode 100644
index 0000000..5e7857f
--- /dev/null
+++ b/opengl/system/GLESv2_enc/gl2_opcodes.h
@@ -0,0 +1,217 @@
+// Generated Code - DO NOT EDIT !!
+// generated by 'emugen'
+#ifndef __GUARD_gl2_opcodes_h_
+#define __GUARD_gl2_opcodes_h_
+
+#define OP_glActiveTexture 					2048
+#define OP_glAttachShader 					2049
+#define OP_glBindAttribLocation 					2050
+#define OP_glBindBuffer 					2051
+#define OP_glBindFramebuffer 					2052
+#define OP_glBindRenderbuffer 					2053
+#define OP_glBindTexture 					2054
+#define OP_glBlendColor 					2055
+#define OP_glBlendEquation 					2056
+#define OP_glBlendEquationSeparate 					2057
+#define OP_glBlendFunc 					2058
+#define OP_glBlendFuncSeparate 					2059
+#define OP_glBufferData 					2060
+#define OP_glBufferSubData 					2061
+#define OP_glCheckFramebufferStatus 					2062
+#define OP_glClear 					2063
+#define OP_glClearColor 					2064
+#define OP_glClearDepthf 					2065
+#define OP_glClearStencil 					2066
+#define OP_glColorMask 					2067
+#define OP_glCompileShader 					2068
+#define OP_glCompressedTexImage2D 					2069
+#define OP_glCompressedTexSubImage2D 					2070
+#define OP_glCopyTexImage2D 					2071
+#define OP_glCopyTexSubImage2D 					2072
+#define OP_glCreateProgram 					2073
+#define OP_glCreateShader 					2074
+#define OP_glCullFace 					2075
+#define OP_glDeleteBuffers 					2076
+#define OP_glDeleteFramebuffers 					2077
+#define OP_glDeleteProgram 					2078
+#define OP_glDeleteRenderbuffers 					2079
+#define OP_glDeleteShader 					2080
+#define OP_glDeleteTextures 					2081
+#define OP_glDepthFunc 					2082
+#define OP_glDepthMask 					2083
+#define OP_glDepthRangef 					2084
+#define OP_glDetachShader 					2085
+#define OP_glDisable 					2086
+#define OP_glDisableVertexAttribArray 					2087
+#define OP_glDrawArrays 					2088
+#define OP_glDrawElements 					2089
+#define OP_glEnable 					2090
+#define OP_glEnableVertexAttribArray 					2091
+#define OP_glFinish 					2092
+#define OP_glFlush 					2093
+#define OP_glFramebufferRenderbuffer 					2094
+#define OP_glFramebufferTexture2D 					2095
+#define OP_glFrontFace 					2096
+#define OP_glGenBuffers 					2097
+#define OP_glGenerateMipmap 					2098
+#define OP_glGenFramebuffers 					2099
+#define OP_glGenRenderbuffers 					2100
+#define OP_glGenTextures 					2101
+#define OP_glGetActiveAttrib 					2102
+#define OP_glGetActiveUniform 					2103
+#define OP_glGetAttachedShaders 					2104
+#define OP_glGetAttribLocation 					2105
+#define OP_glGetBooleanv 					2106
+#define OP_glGetBufferParameteriv 					2107
+#define OP_glGetError 					2108
+#define OP_glGetFloatv 					2109
+#define OP_glGetFramebufferAttachmentParameteriv 					2110
+#define OP_glGetIntegerv 					2111
+#define OP_glGetProgramiv 					2112
+#define OP_glGetProgramInfoLog 					2113
+#define OP_glGetRenderbufferParameteriv 					2114
+#define OP_glGetShaderiv 					2115
+#define OP_glGetShaderInfoLog 					2116
+#define OP_glGetShaderPrecisionFormat 					2117
+#define OP_glGetShaderSource 					2118
+#define OP_glGetString 					2119
+#define OP_glGetTexParameterfv 					2120
+#define OP_glGetTexParameteriv 					2121
+#define OP_glGetUniformfv 					2122
+#define OP_glGetUniformiv 					2123
+#define OP_glGetUniformLocation 					2124
+#define OP_glGetVertexAttribfv 					2125
+#define OP_glGetVertexAttribiv 					2126
+#define OP_glGetVertexAttribPointerv 					2127
+#define OP_glHint 					2128
+#define OP_glIsBuffer 					2129
+#define OP_glIsEnabled 					2130
+#define OP_glIsFramebuffer 					2131
+#define OP_glIsProgram 					2132
+#define OP_glIsRenderbuffer 					2133
+#define OP_glIsShader 					2134
+#define OP_glIsTexture 					2135
+#define OP_glLineWidth 					2136
+#define OP_glLinkProgram 					2137
+#define OP_glPixelStorei 					2138
+#define OP_glPolygonOffset 					2139
+#define OP_glReadPixels 					2140
+#define OP_glReleaseShaderCompiler 					2141
+#define OP_glRenderbufferStorage 					2142
+#define OP_glSampleCoverage 					2143
+#define OP_glScissor 					2144
+#define OP_glShaderBinary 					2145
+#define OP_glShaderSource 					2146
+#define OP_glStencilFunc 					2147
+#define OP_glStencilFuncSeparate 					2148
+#define OP_glStencilMask 					2149
+#define OP_glStencilMaskSeparate 					2150
+#define OP_glStencilOp 					2151
+#define OP_glStencilOpSeparate 					2152
+#define OP_glTexImage2D 					2153
+#define OP_glTexParameterf 					2154
+#define OP_glTexParameterfv 					2155
+#define OP_glTexParameteri 					2156
+#define OP_glTexParameteriv 					2157
+#define OP_glTexSubImage2D 					2158
+#define OP_glUniform1f 					2159
+#define OP_glUniform1fv 					2160
+#define OP_glUniform1i 					2161
+#define OP_glUniform1iv 					2162
+#define OP_glUniform2f 					2163
+#define OP_glUniform2fv 					2164
+#define OP_glUniform2i 					2165
+#define OP_glUniform2iv 					2166
+#define OP_glUniform3f 					2167
+#define OP_glUniform3fv 					2168
+#define OP_glUniform3i 					2169
+#define OP_glUniform3iv 					2170
+#define OP_glUniform4f 					2171
+#define OP_glUniform4fv 					2172
+#define OP_glUniform4i 					2173
+#define OP_glUniform4iv 					2174
+#define OP_glUniformMatrix2fv 					2175
+#define OP_glUniformMatrix3fv 					2176
+#define OP_glUniformMatrix4fv 					2177
+#define OP_glUseProgram 					2178
+#define OP_glValidateProgram 					2179
+#define OP_glVertexAttrib1f 					2180
+#define OP_glVertexAttrib1fv 					2181
+#define OP_glVertexAttrib2f 					2182
+#define OP_glVertexAttrib2fv 					2183
+#define OP_glVertexAttrib3f 					2184
+#define OP_glVertexAttrib3fv 					2185
+#define OP_glVertexAttrib4f 					2186
+#define OP_glVertexAttrib4fv 					2187
+#define OP_glVertexAttribPointer 					2188
+#define OP_glViewport 					2189
+#define OP_glEGLImageTargetTexture2DOES 					2190
+#define OP_glEGLImageTargetRenderbufferStorageOES 					2191
+#define OP_glGetProgramBinaryOES 					2192
+#define OP_glProgramBinaryOES 					2193
+#define OP_glMapBufferOES 					2194
+#define OP_glUnmapBufferOES 					2195
+#define OP_glTexImage3DOES 					2196
+#define OP_glTexSubImage3DOES 					2197
+#define OP_glCopyTexSubImage3DOES 					2198
+#define OP_glCompressedTexImage3DOES 					2199
+#define OP_glCompressedTexSubImage3DOES 					2200
+#define OP_glFramebufferTexture3DOES 					2201
+#define OP_glBindVertexArrayOES 					2202
+#define OP_glDeleteVertexArraysOES 					2203
+#define OP_glGenVertexArraysOES 					2204
+#define OP_glIsVertexArrayOES 					2205
+#define OP_glDiscardFramebufferEXT 					2206
+#define OP_glMultiDrawArraysEXT 					2207
+#define OP_glMultiDrawElementsEXT 					2208
+#define OP_glGetPerfMonitorGroupsAMD 					2209
+#define OP_glGetPerfMonitorCountersAMD 					2210
+#define OP_glGetPerfMonitorGroupStringAMD 					2211
+#define OP_glGetPerfMonitorCounterStringAMD 					2212
+#define OP_glGetPerfMonitorCounterInfoAMD 					2213
+#define OP_glGenPerfMonitorsAMD 					2214
+#define OP_glDeletePerfMonitorsAMD 					2215
+#define OP_glSelectPerfMonitorCountersAMD 					2216
+#define OP_glBeginPerfMonitorAMD 					2217
+#define OP_glEndPerfMonitorAMD 					2218
+#define OP_glGetPerfMonitorCounterDataAMD 					2219
+#define OP_glRenderbufferStorageMultisampleIMG 					2220
+#define OP_glFramebufferTexture2DMultisampleIMG 					2221
+#define OP_glDeleteFencesNV 					2222
+#define OP_glGenFencesNV 					2223
+#define OP_glIsFenceNV 					2224
+#define OP_glTestFenceNV 					2225
+#define OP_glGetFenceivNV 					2226
+#define OP_glFinishFenceNV 					2227
+#define OP_glSetFenceNV 					2228
+#define OP_glCoverageMaskNV 					2229
+#define OP_glCoverageOperationNV 					2230
+#define OP_glGetDriverControlsQCOM 					2231
+#define OP_glGetDriverControlStringQCOM 					2232
+#define OP_glEnableDriverControlQCOM 					2233
+#define OP_glDisableDriverControlQCOM 					2234
+#define OP_glExtGetTexturesQCOM 					2235
+#define OP_glExtGetBuffersQCOM 					2236
+#define OP_glExtGetRenderbuffersQCOM 					2237
+#define OP_glExtGetFramebuffersQCOM 					2238
+#define OP_glExtGetTexLevelParameterivQCOM 					2239
+#define OP_glExtTexObjectStateOverrideiQCOM 					2240
+#define OP_glExtGetTexSubImageQCOM 					2241
+#define OP_glExtGetBufferPointervQCOM 					2242
+#define OP_glExtGetShadersQCOM 					2243
+#define OP_glExtGetProgramsQCOM 					2244
+#define OP_glExtIsProgramBinaryQCOM 					2245
+#define OP_glExtGetProgramBinarySourceQCOM 					2246
+#define OP_glStartTilingQCOM 					2247
+#define OP_glEndTilingQCOM 					2248
+#define OP_glVertexAttribPointerData 					2249
+#define OP_glVertexAttribPointerOffset 					2250
+#define OP_glDrawElementsOffset 					2251
+#define OP_glDrawElementsData 					2252
+#define OP_glGetCompressedTextureFormats 					2253
+#define OP_glShaderString 					2254
+#define OP_glFinishRoundTrip 					2255
+#define OP_last 					2256
+
+
+#endif
diff --git a/opengl/system/GLESv2_enc/gl2_types.h b/opengl/system/GLESv2_enc/gl2_types.h
new file mode 100644
index 0000000..bfff61d
--- /dev/null
+++ b/opengl/system/GLESv2_enc/gl2_types.h
@@ -0,0 +1,21 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#ifndef _GL_2_TYPES_H_
+#define _GL_2_TYPES_H_
+#include "gl_base_types.h"
+
+typedef void *GLvoidptr;
+#endif
diff --git a/opengl/system/OpenglSystemCommon/Android.mk b/opengl/system/OpenglSystemCommon/Android.mk
new file mode 100644
index 0000000..6198748
--- /dev/null
+++ b/opengl/system/OpenglSystemCommon/Android.mk
@@ -0,0 +1,13 @@
+LOCAL_PATH := $(call my-dir)
+
+$(call emugl-begin-shared-library,libOpenglSystemCommon)
+$(call emugl-import,libGLESv1_enc libGLESv2_enc lib_renderControl_enc)
+
+LOCAL_SRC_FILES := \
+    HostConnection.cpp \
+    QemuPipeStream.cpp \
+    ThreadInfo.cpp
+
+$(call emugl-export,C_INCLUDES,$(LOCAL_PATH) bionic/libc/private)
+
+$(call emugl-end-module)
diff --git a/opengl/system/OpenglSystemCommon/EGLClientIface.h b/opengl/system/OpenglSystemCommon/EGLClientIface.h
new file mode 100644
index 0000000..3c8cb55
--- /dev/null
+++ b/opengl/system/OpenglSystemCommon/EGLClientIface.h
@@ -0,0 +1,41 @@
+/*
+* Copyright 2011 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.
+*/
+
+#ifndef _SYSTEM_COMMON_EGL_CLIENT_IFACE_H
+#define _SYSTEM_COMMON_EGL_CLIENT_IFACE_H
+
+struct EGLThreadInfo;  // defined in ThreadInfo.h
+
+typedef struct {
+    EGLThreadInfo* (*getThreadInfo)();
+    const char* (*getGLString)(int glEnum);
+} EGLClient_eglInterface;
+
+typedef struct {
+    void* (*getProcAddress)(const char *funcName);
+    void (*init)();
+    void (*finish)();
+} EGLClient_glesInterface;
+
+//
+// Any GLES/GLES2 client API library should define a function named "init_emul_gles"
+// with the following prototype,
+// It will be called by EGL after loading the GLES library for initialization
+// and exchanging interface function pointers.
+//
+typedef EGLClient_glesInterface *(*init_emul_gles_t)(EGLClient_eglInterface *eglIface);
+
+#endif
diff --git a/opengl/system/OpenglSystemCommon/HostConnection.cpp b/opengl/system/OpenglSystemCommon/HostConnection.cpp
new file mode 100644
index 0000000..940f5ae
--- /dev/null
+++ b/opengl/system/OpenglSystemCommon/HostConnection.cpp
@@ -0,0 +1,153 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#include "HostConnection.h"
+#include "TcpStream.h"
+#include "QemuPipeStream.h"
+#include "ThreadInfo.h"
+#include <cutils/log.h>
+#include "GLEncoder.h"
+#include "GL2Encoder.h"
+
+#define STREAM_BUFFER_SIZE  4*1024*1024
+#define STREAM_PORT_NUM     22468
+
+/* Set to 1 to use a QEMU pipe, or 0 for a TCP connection */
+#define  USE_QEMU_PIPE  1
+
+HostConnection::HostConnection() :
+    m_stream(NULL),
+    m_glEnc(NULL),
+    m_gl2Enc(NULL),
+    m_rcEnc(NULL)
+{
+}
+
+HostConnection::~HostConnection()
+{
+    delete m_stream;
+    delete m_glEnc;
+    delete m_gl2Enc;
+    delete m_rcEnc;
+}
+
+HostConnection *HostConnection::get()
+{
+    /* TODO: Make this configurable with a system property */
+    const int useQemuPipe = USE_QEMU_PIPE;
+
+    // Get thread info
+    EGLThreadInfo *tinfo = getEGLThreadInfo();
+    if (!tinfo) {
+        return NULL;
+    }
+
+    if (tinfo->hostConn == NULL) {
+        HostConnection *con = new HostConnection();
+        if (NULL == con) {
+            return NULL;
+        }
+
+        if (useQemuPipe) {
+            QemuPipeStream *stream = new QemuPipeStream(STREAM_BUFFER_SIZE);
+            if (!stream) {
+                ALOGE("Failed to create QemuPipeStream for host connection!!!\n");
+                delete con;
+                return NULL;
+            }
+            if (stream->connect() < 0) {
+                ALOGE("Failed to connect to host (QemuPipeStream)!!!\n");
+                delete stream;
+                delete con;
+                return NULL;
+            }
+            con->m_stream = stream;
+        }
+        else /* !useQemuPipe */
+        {
+            TcpStream *stream = new TcpStream(STREAM_BUFFER_SIZE);
+            if (!stream) {
+                ALOGE("Failed to create TcpStream for host connection!!!\n");
+                delete con;
+                return NULL;
+            }
+
+            if (stream->connect("10.0.2.2", STREAM_PORT_NUM) < 0) {
+                ALOGE("Failed to connect to host (TcpStream)!!!\n");
+                delete stream;
+                delete con;
+                return NULL;
+            }
+            con->m_stream = stream;
+        }
+
+        // send zero 'clientFlags' to the host.
+        unsigned int *pClientFlags =
+                (unsigned int *)con->m_stream->allocBuffer(sizeof(unsigned int));
+        *pClientFlags = 0;
+        con->m_stream->commitBuffer(sizeof(unsigned int));
+
+        ALOGD("HostConnection::get() New Host Connection established %p, tid %d\n", con, gettid());
+        tinfo->hostConn = con;
+    }
+
+    return tinfo->hostConn;
+}
+
+GLEncoder *HostConnection::glEncoder()
+{
+    if (!m_glEnc) {
+        m_glEnc = new GLEncoder(m_stream);
+        DBG("HostConnection::glEncoder new encoder %p, tid %d", m_glEnc, gettid());
+        m_glEnc->setContextAccessor(s_getGLContext);
+    }
+    return m_glEnc;
+}
+
+GL2Encoder *HostConnection::gl2Encoder()
+{
+    if (!m_gl2Enc) {
+        m_gl2Enc = new GL2Encoder(m_stream);
+        DBG("HostConnection::gl2Encoder new encoder %p, tid %d", m_gl2Enc, gettid());
+        m_gl2Enc->setContextAccessor(s_getGL2Context);
+    }
+    return m_gl2Enc;
+}
+
+renderControl_encoder_context_t *HostConnection::rcEncoder()
+{
+    if (!m_rcEnc) {
+        m_rcEnc = new renderControl_encoder_context_t(m_stream);
+    }
+    return m_rcEnc;
+}
+
+gl_client_context_t *HostConnection::s_getGLContext()
+{
+    EGLThreadInfo *ti = getEGLThreadInfo();
+    if (ti->hostConn) {
+        return ti->hostConn->m_glEnc;
+    }
+    return NULL;
+}
+
+gl2_client_context_t *HostConnection::s_getGL2Context()
+{
+    EGLThreadInfo *ti = getEGLThreadInfo();
+    if (ti->hostConn) {
+        return ti->hostConn->m_gl2Enc;
+    }
+    return NULL;
+}
diff --git a/opengl/system/OpenglSystemCommon/HostConnection.h b/opengl/system/OpenglSystemCommon/HostConnection.h
new file mode 100644
index 0000000..e7a5ac4
--- /dev/null
+++ b/opengl/system/OpenglSystemCommon/HostConnection.h
@@ -0,0 +1,55 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#ifndef __COMMON_HOST_CONNECTION_H
+#define __COMMON_HOST_CONNECTION_H
+
+#include "IOStream.h"
+#include "renderControl_enc.h"
+
+class GLEncoder;
+class gl_client_context_t;
+class GL2Encoder;
+class gl2_client_context_t;
+
+class HostConnection
+{
+public:
+    static HostConnection *get();
+    ~HostConnection();
+
+    GLEncoder *glEncoder();
+    GL2Encoder *gl2Encoder();
+    renderControl_encoder_context_t *rcEncoder();
+
+    void flush() {
+        if (m_stream) {
+            m_stream->flush();
+        }
+    }
+
+private:
+    HostConnection();
+    static gl_client_context_t  *s_getGLContext();
+    static gl2_client_context_t *s_getGL2Context();
+
+private:
+    IOStream *m_stream;
+    GLEncoder   *m_glEnc;
+    GL2Encoder  *m_gl2Enc;
+    renderControl_encoder_context_t *m_rcEnc;
+};
+
+#endif
diff --git a/opengl/system/OpenglSystemCommon/QemuPipeStream.cpp b/opengl/system/OpenglSystemCommon/QemuPipeStream.cpp
new file mode 100644
index 0000000..50c3d8b
--- /dev/null
+++ b/opengl/system/OpenglSystemCommon/QemuPipeStream.cpp
@@ -0,0 +1,190 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#include "QemuPipeStream.h"
+#include <hardware/qemu_pipe.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+QemuPipeStream::QemuPipeStream(size_t bufSize) :
+    IOStream(bufSize),
+    m_sock(-1),
+    m_bufsize(bufSize),
+    m_buf(NULL)
+{
+}
+
+QemuPipeStream::QemuPipeStream(int sock, size_t bufSize) :
+    IOStream(bufSize),
+    m_sock(sock),
+    m_bufsize(bufSize),
+    m_buf(NULL)
+{
+}
+
+QemuPipeStream::~QemuPipeStream()
+{
+    if (m_sock >= 0) {
+        ::close(m_sock);
+    }
+    if (m_buf != NULL) {
+        free(m_buf);
+    }
+}
+
+
+int QemuPipeStream::connect(void)
+{
+    m_sock = qemu_pipe_open("opengles");
+    if (!valid()) return -1;
+    return 0;
+}
+
+void *QemuPipeStream::allocBuffer(size_t minSize)
+{
+    size_t allocSize = (m_bufsize < minSize ? minSize : m_bufsize);
+    if (!m_buf) {
+        m_buf = (unsigned char *)malloc(allocSize);
+    }
+    else if (m_bufsize < allocSize) {
+        unsigned char *p = (unsigned char *)realloc(m_buf, allocSize);
+        if (p != NULL) {
+            m_buf = p;
+            m_bufsize = allocSize;
+        } else {
+            ERR("realloc (%d) failed\n", allocSize);
+            free(m_buf);
+            m_buf = NULL;
+            m_bufsize = 0;
+        }
+    }
+
+    return m_buf;
+};
+
+int QemuPipeStream::commitBuffer(size_t size)
+{
+    return writeFully(m_buf, size);
+}
+
+int QemuPipeStream::writeFully(const void *buf, size_t len)
+{
+    //DBG(">> QemuPipeStream::writeFully %d\n", len);
+    if (!valid()) return -1;
+
+    size_t res = len;
+    int retval = 0;
+
+    while (res > 0) {
+        ssize_t stat = ::write(m_sock, (const char *)(buf) + (len - res), res);
+        if (stat > 0) {
+            res -= stat;
+            continue;
+        }
+        if (stat == 0) { /* EOF */
+            ERR("QemuPipeStream::writeFully failed: premature EOF\n");
+            retval = -1;
+            break;
+        }
+        if (errno == EINTR) {
+            continue;
+        }
+        retval =  stat;
+        ERR("QemuPipeStream::writeFully failed: %s\n", strerror(errno));
+        break;
+    }
+    //DBG("<< QemuPipeStream::writeFully %d\n", len );
+    return retval;
+}
+
+const unsigned char *QemuPipeStream::readFully(void *buf, size_t len)
+{
+    //DBG(">> QemuPipeStream::readFully %d\n", len);
+    if (!valid()) return NULL;
+    if (!buf) {
+        if (len>0) ERR("QemuPipeStream::readFully failed, buf=NULL, len %d", len);
+        return NULL;  // do not allow NULL buf in that implementation
+    }
+    size_t res = len;
+    while (res > 0) {
+        ssize_t stat = ::read(m_sock, (char *)(buf) + len - res, len);
+        if (stat == 0) {
+            // client shutdown;
+            return NULL;
+        } else if (stat < 0) {
+            if (errno == EINTR) {
+                continue;
+            } else {
+                ERR("QemuPipeStream::readFully failed (buf %p): %s\n",
+                    buf, strerror(errno));
+                return NULL;
+            }
+        } else {
+            res -= stat;
+        }
+    }
+    //DBG("<< QemuPipeStream::readFully %d\n", len);
+    return (const unsigned char *)buf;
+}
+
+const unsigned char *QemuPipeStream::read( void *buf, size_t *inout_len)
+{
+    //DBG(">> QemuPipeStream::read %d\n", *inout_len);
+    if (!valid()) return NULL;
+    if (!buf) {
+      ERR("QemuPipeStream::read failed, buf=NULL");
+      return NULL;  // do not allow NULL buf in that implementation
+    }
+
+    int n = recv(buf, *inout_len);
+
+    if (n > 0) {
+        *inout_len = n;
+        return (const unsigned char *)buf;
+    }
+
+    //DBG("<< QemuPipeStream::read %d\n", *inout_len);
+    return NULL;
+}
+
+int QemuPipeStream::recv(void *buf, size_t len)
+{
+    if (!valid()) return int(ERR_INVALID_SOCKET);
+    char* p = (char *)buf;
+    int ret = 0;
+    while(len > 0) {
+        int res = ::read(m_sock, p, len);
+        if (res > 0) {
+            p += res;
+            ret += res;
+            len -= res;
+            continue;
+        }
+        if (res == 0) { /* EOF */
+             break;
+        }
+        if (errno == EINTR)
+            continue;
+
+        /* A real error */
+        if (ret == 0)
+            ret = -1;
+        break;
+    }
+    return ret;
+}
diff --git a/opengl/system/OpenglSystemCommon/QemuPipeStream.h b/opengl/system/OpenglSystemCommon/QemuPipeStream.h
new file mode 100644
index 0000000..57ee399
--- /dev/null
+++ b/opengl/system/OpenglSystemCommon/QemuPipeStream.h
@@ -0,0 +1,51 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#ifndef __QEMU_PIPE_STREAM_H
+#define __QEMU_PIPE_STREAM_H
+
+/* This file implements an IOStream that uses a QEMU fast-pipe
+ * to communicate with the emulator's 'opengles' service. See
+ * <hardware/qemu_pipe.h> for more details.
+ */
+#include <stdlib.h>
+#include "IOStream.h"
+
+class QemuPipeStream : public IOStream {
+public:
+    typedef enum { ERR_INVALID_SOCKET = -1000 } QemuPipeStreamError;
+
+    explicit QemuPipeStream(size_t bufsize = 10000);
+    ~QemuPipeStream();
+    int connect(void);
+
+    virtual void *allocBuffer(size_t minSize);
+    virtual int commitBuffer(size_t size);
+    virtual const unsigned char *readFully( void *buf, size_t len);
+    virtual const unsigned char *read( void *buf, size_t *inout_len);
+
+    bool valid() { return m_sock >= 0; }
+    int recv(void *buf, size_t len);
+
+    virtual int writeFully(const void *buf, size_t len);
+
+private:
+    int m_sock;
+    size_t m_bufsize;
+    unsigned char *m_buf;
+    QemuPipeStream(int sock, size_t bufSize);
+};
+
+#endif
diff --git a/opengl/system/OpenglSystemCommon/ThreadInfo.cpp b/opengl/system/OpenglSystemCommon/ThreadInfo.cpp
new file mode 100644
index 0000000..75da8f2
--- /dev/null
+++ b/opengl/system/OpenglSystemCommon/ThreadInfo.cpp
@@ -0,0 +1,39 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#include "ThreadInfo.h"
+#include "cutils/threads.h"
+
+thread_store_t s_tls = THREAD_STORE_INITIALIZER;
+
+static void tlsDestruct(void *ptr)
+{
+    if (ptr) {
+        EGLThreadInfo *ti = (EGLThreadInfo *)ptr;
+        delete ti->hostConn;
+        delete ti;
+    }
+}
+
+EGLThreadInfo *slow_getEGLThreadInfo()
+{
+    EGLThreadInfo *ti = (EGLThreadInfo *)thread_store_get(&s_tls);
+    if (ti) return ti;
+
+    ti = new EGLThreadInfo();
+    thread_store_set(&s_tls, ti, tlsDestruct);
+
+    return ti;
+}
diff --git a/opengl/system/OpenglSystemCommon/ThreadInfo.h b/opengl/system/OpenglSystemCommon/ThreadInfo.h
new file mode 100644
index 0000000..0328733
--- /dev/null
+++ b/opengl/system/OpenglSystemCommon/ThreadInfo.h
@@ -0,0 +1,59 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#ifndef _THREAD_INFO_H
+#define _THREAD_INFO_H
+
+#include "HostConnection.h"
+#include <pthread.h>
+#ifdef HAVE_ANDROID_OS
+#include <bionic_tls.h>
+#endif
+
+struct EGLContext_t;
+
+struct EGLThreadInfo
+{
+    EGLThreadInfo() : currentContext(NULL), hostConn(NULL), eglError(EGL_SUCCESS) {}
+
+    EGLContext_t *currentContext;
+    HostConnection *hostConn;
+    int           eglError;
+};
+
+
+EGLThreadInfo *slow_getEGLThreadInfo();
+
+#ifdef HAVE_ANDROID_OS
+    // We have a dedicated TLS slot in bionic
+    inline EGLThreadInfo* getEGLThreadInfo() {
+        EGLThreadInfo *tInfo =
+             (EGLThreadInfo *)(((unsigned *)__get_tls())[TLS_SLOT_OPENGL]);
+        if (!tInfo) {
+            tInfo = slow_getEGLThreadInfo();
+            ((uint32_t *)__get_tls())[TLS_SLOT_OPENGL] = (uint32_t)tInfo;
+        }
+        return tInfo;
+    }
+#else
+    inline EGLThreadInfo* getEGLThreadInfo() {
+        return slow_getEGLThreadInfo();
+    }
+#endif
+
+
+
+
+#endif // of _THREAD_INFO_H
diff --git a/opengl/system/OpenglSystemCommon/gralloc_cb.h b/opengl/system/OpenglSystemCommon/gralloc_cb.h
new file mode 100644
index 0000000..a207401
--- /dev/null
+++ b/opengl/system/OpenglSystemCommon/gralloc_cb.h
@@ -0,0 +1,108 @@
+/*
+* Copyright 2011 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.
+*/
+
+#ifndef __GRALLOC_CB_H__
+#define __GRALLOC_CB_H__
+
+#include <hardware/hardware.h>
+#include <hardware/gralloc.h>
+#include <cutils/native_handle.h>
+
+#define BUFFER_HANDLE_MAGIC ((int)0xabfabfab)
+#define CB_HANDLE_NUM_INTS(nfds) (int)((sizeof(cb_handle_t) - (nfds)*sizeof(int)) / sizeof(int))
+
+//
+// Our buffer handle structure
+//
+struct cb_handle_t : public native_handle {
+
+    cb_handle_t(int p_fd, int p_ashmemSize, int p_usage,
+                int p_width, int p_height, int p_format,
+                int p_glFormat, int p_glType) :
+        fd(p_fd),
+        magic(BUFFER_HANDLE_MAGIC),
+        usage(p_usage),
+        width(p_width),
+        height(p_height),
+        format(p_format),
+        glFormat(p_glFormat),
+        glType(p_glType),
+        ashmemSize(p_ashmemSize),
+        ashmemBase(0),
+        ashmemBasePid(0),
+        mappedPid(0),
+        lockedLeft(0),
+        lockedTop(0),
+        lockedWidth(0),
+        lockedHeight(0),
+        hostHandle(0)
+    {
+        version = sizeof(native_handle);
+        numFds = 0;
+        numInts = CB_HANDLE_NUM_INTS(numFds);
+    }
+
+    ~cb_handle_t() {
+        magic = 0;
+    }
+
+    void setFd(int p_fd) {
+        if (p_fd >= 0) {
+            numFds = 1;
+        }
+        else {
+            numFds = 0;
+        }
+        fd = p_fd;
+        numInts = CB_HANDLE_NUM_INTS(numFds);
+    }
+
+    static bool validate(cb_handle_t * hnd) {
+        return (hnd && 
+                hnd->version == sizeof(native_handle) &&
+                hnd->magic == BUFFER_HANDLE_MAGIC &&
+                hnd->numInts == CB_HANDLE_NUM_INTS(hnd->numFds));
+    }
+
+    bool canBePosted() {
+        return (0 != (usage & GRALLOC_USAGE_HW_FB));
+    }
+
+    // file-descriptors
+    int fd;  // ashmem fd (-1 of ashmem region did not allocated, i.e. no SW access needed)
+
+    // ints
+    int magic;              // magic number in order to validate a pointer to be a cb_handle_t
+    int usage;              // usage bits the buffer was created with
+    int width;              // buffer width
+    int height;             // buffer height
+    int format;             // real internal pixel format format
+    int glFormat;           // OpenGL format enum used for host h/w color buffer
+    int glType;             // OpenGL type enum used when uploading to host
+    int ashmemSize;         // ashmem region size for the buffer (0 unless is HW_FB buffer or
+                            //                                    s/w access is needed)
+    int ashmemBase;         // CPU address of the mapped ashmem region
+    int ashmemBasePid;      // process id which mapped the ashmem region
+    int mappedPid;          // process id which succeeded gralloc_register call
+    int lockedLeft;         // region of buffer locked for s/w write
+    int lockedTop;
+    int lockedWidth;
+    int lockedHeight;
+    uint32_t hostHandle;
+};
+
+
+#endif //__GRALLOC_CB_H__
diff --git a/opengl/system/egl/Android.mk b/opengl/system/egl/Android.mk
new file mode 100644
index 0000000..a979089
--- /dev/null
+++ b/opengl/system/egl/Android.mk
@@ -0,0 +1,41 @@
+ifneq (false,$(BUILD_EMULATOR_OPENGL_DRIVER))
+
+LOCAL_PATH := $(call my-dir)
+
+$(call emugl-begin-shared-library,libEGL_emulation)
+$(call emugl-import,libOpenglSystemCommon)
+$(call emugl-set-shared-library-subpath,egl)
+
+LOCAL_CFLAGS += -DLOG_TAG=\"EGL_emulation\" -DEGL_EGLEXT_PROTOTYPES -DWITH_GLES2
+
+LOCAL_SRC_FILES := \
+    eglDisplay.cpp \
+    egl.cpp \
+    ClientAPIExts.cpp
+
+LOCAL_SHARED_LIBRARIES += libdl
+
+# Used to access the Bionic private OpenGL TLS slot
+LOCAL_C_INCLUDES += bionic/libc/private
+
+$(call emugl-end-module)
+
+#### egl.cfg ####
+
+# Ensure that this file is only copied to emulator-specific builds.
+# Other builds are device-specific and will provide their own
+# version of this file to point to the appropriate HW EGL libraries.
+#
+ifneq (,$(filter full full_x86 full_mips sdk sdk_x86 sdk_mips google_sdk google_sdk_x86 google_sdk_mips,$(TARGET_PRODUCT)))
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := egl.cfg
+LOCAL_SRC_FILES := $(LOCAL_MODULE)
+
+LOCAL_MODULE_PATH := $(TARGET_OUT)/lib/egl
+LOCAL_MODULE_CLASS := ETC
+
+include $(BUILD_PREBUILT)
+endif # TARGET_PRODUCT in 'full full_x86 full_mips sdk sdk_x86 sdk_mips google_sdk google_sdk_x86 google_sdk_mips')
+
+endif # BUILD_EMULATOR_OPENGL_DRIVER != false
diff --git a/opengl/system/egl/ClientAPIExts.cpp b/opengl/system/egl/ClientAPIExts.cpp
new file mode 100644
index 0000000..5e81afe
--- /dev/null
+++ b/opengl/system/egl/ClientAPIExts.cpp
@@ -0,0 +1,157 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#include "ClientAPIExts.h"
+#include "ThreadInfo.h"
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+#include "eglContext.h"
+
+namespace ClientAPIExts
+{
+
+//
+// define function pointer type for each extention function
+// typename has the form __egl_{funcname}_t
+//
+#define FUNC_TYPE(fname) __egl_ ## fname ## _t
+#define API_ENTRY(fname,params,args) \
+    typedef void (GL_APIENTRY *FUNC_TYPE(fname)) params;
+
+#define API_ENTRY_RET(rtype,fname,params,args) \
+    typedef rtype (GL_APIENTRY *FUNC_TYPE(fname)) params;
+
+#include "ClientAPIExts.in"
+#undef API_ENTRY
+#undef API_ENTRY_RET
+
+/////
+// Define static table to store the function value for each
+// client API. functions pointers will get initialized through
+// ClientAPIExts::initClientFuncs function after each client API has been
+// loaded.
+/////
+#define API_ENTRY(fname,params,args) \
+    FUNC_TYPE(fname) fname;
+
+#define API_ENTRY_RET(rtype,fname,params,args) \
+    API_ENTRY(fname,params,args)
+
+static struct _ext_table
+{
+#include "ClientAPIExts.in"
+} s_client_extensions[2];
+
+#undef API_ENTRY
+#undef API_ENTRY_RET
+
+//
+// This function initialized each entry in the s_client_extensions
+// struct at the givven index using the givven client interface
+//
+void initClientFuncs(const EGLClient_glesInterface *iface, int idx)
+{
+#define API_ENTRY(fname,params,args) \
+    s_client_extensions[idx].fname = \
+          (FUNC_TYPE(fname))iface->getProcAddress(#fname);
+
+#define API_ENTRY_RET(rtype,fname,params,args) \
+    API_ENTRY(fname,params,args)
+
+    //
+    // reset all func pointers to NULL
+    //
+    memset(&s_client_extensions[idx], 0, sizeof(struct _ext_table));
+
+    //
+    // And now query the GLES library for each proc address
+    //
+#include "ClientAPIExts.in"
+#undef API_ENTRY
+#undef API_ENTRY_RET
+}
+
+//
+// Define implementation for each extension function which checks
+// the current context version and calls to the correct client API
+// function.
+//
+#define API_ENTRY(fname,params,args) \
+    static void _egl_ ## fname params \
+    { \
+        EGLThreadInfo* thread  = getEGLThreadInfo(); \
+        if (!thread->currentContext) { \
+            return; \
+        } \
+        int idx = (int)thread->currentContext->version - 1; \
+        if (!s_client_extensions[idx].fname) { \
+            return; \
+        } \
+        (*s_client_extensions[idx].fname) args; \
+    }
+
+#define API_ENTRY_RET(rtype,fname,params,args) \
+    static rtype _egl_ ## fname params \
+    { \
+        EGLThreadInfo* thread  = getEGLThreadInfo(); \
+        if (!thread->currentContext) { \
+            return (rtype)0; \
+        } \
+        int idx = (int)thread->currentContext->version - 1; \
+        if (!s_client_extensions[idx].fname) { \
+            return (rtype)0; \
+        } \
+        return (*s_client_extensions[idx].fname) args; \
+    }
+
+#include "ClientAPIExts.in"
+#undef API_ENTRY
+#undef API_ENTRY_RET
+
+//
+// Define a table to map function names to the local _egl_ version of
+// the extension function, to be used in eglGetProcAddress.
+//
+#define API_ENTRY(fname,params,args) \
+    { #fname, (void*)_egl_ ## fname},
+#define API_ENTRY_RET(rtype,fname,params,args) \
+    API_ENTRY(fname,params,args)
+
+static const struct _client_ext_funcs {
+    const char *fname;
+    void* proc;
+} s_client_ext_funcs[] = {
+#include "ClientAPIExts.in"
+};
+static const int numExtFuncs = sizeof(s_client_ext_funcs) / 
+                               sizeof(s_client_ext_funcs[0]);
+
+#undef API_ENTRY
+#undef API_ENTRY_RET
+
+//
+// returns the __egl_ version of the givven extension function name.
+//
+void* getProcAddress(const char *fname)
+{
+    for (int i=0; i<numExtFuncs; i++) {
+        if (!strcmp(fname, s_client_ext_funcs[i].fname)) {
+            return s_client_ext_funcs[i].proc;
+        }
+    }
+    return NULL;
+}
+
+} // of namespace ClientAPIExts
diff --git a/opengl/system/egl/ClientAPIExts.h b/opengl/system/egl/ClientAPIExts.h
new file mode 100644
index 0000000..eee9172
--- /dev/null
+++ b/opengl/system/egl/ClientAPIExts.h
@@ -0,0 +1,29 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#ifndef _CLIENT_APIS_EXTS_H
+#define _CLIENT_APIS_EXTS_H
+
+#include "EGLClientIface.h"
+
+namespace ClientAPIExts
+{
+
+void initClientFuncs(const EGLClient_glesInterface *iface, int idx);
+void* getProcAddress(const char *fname);
+
+} // of namespace ClientAPIExts
+
+#endif
diff --git a/opengl/system/egl/ClientAPIExts.in b/opengl/system/egl/ClientAPIExts.in
new file mode 100644
index 0000000..5850701
--- /dev/null
+++ b/opengl/system/egl/ClientAPIExts.in
@@ -0,0 +1,201 @@
+//
+// Each extension function should have one of the following
+// macro definitions:
+//    API_ENTRY(funcname, paramlist, arglist)
+//  -or- (if the function has a return value)
+//    API_ENTRY_RET(return_type,funcname, paramlist, arglist)
+//
+API_ENTRY(glEGLImageTargetTexture2DOES,
+          (GLenum target, GLeglImageOES image),
+          (target, image))
+
+API_ENTRY(glEGLImageTargetRenderbufferStorageOES,
+          (GLenum target, GLeglImageOES image),
+          (target, image))
+
+API_ENTRY(glBlendEquationSeparateOES,
+          (GLenum modeRGB, GLenum modeAlpha),
+          (modeRGB, modeAlpha))
+
+API_ENTRY(glBlendFuncSeparateOES,
+          (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha),
+          (srcRGB, dstRGB, srcAlpha, dstAlpha))
+
+API_ENTRY(glBlendEquationOES,
+          (GLenum mode),
+          (mode))
+
+API_ENTRY(glCurrentPaletteMatrixOES,
+          (GLuint matrixpaletteindex),
+          (matrixpaletteindex))
+
+API_ENTRY(glLoadPaletteFromModelViewMatrixOES,
+          (void),
+          ())
+
+API_ENTRY(glMatrixIndexPointerOES,
+          (GLint size, GLenum type, GLsizei stride, const GLvoid * pointer),
+          (size, type, stride, pointer))
+
+API_ENTRY(glWeightPointerOES,
+          (GLint size, GLenum type, GLsizei stride, const GLvoid * pointer),
+          (size, type, stride, pointer))
+
+API_ENTRY(glDepthRangefOES,
+          (GLclampf zNear, GLclampf zFar),
+          (zNear, zFar))
+
+API_ENTRY(glFrustumfOES,
+          (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar),
+          (left, right, bottom, top, zNear, zFar))
+
+API_ENTRY(glOrthofOES,
+          (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar),
+          (left, right, bottom, top, zNear, zFar))
+
+API_ENTRY(glClipPlanefOES,
+          (GLenum plane, const GLfloat *equation),
+          (plane, equation))
+
+API_ENTRY(glGetClipPlanefOES,
+          (GLenum pname, GLfloat * eqn),
+          (pname, eqn))
+
+API_ENTRY(glClearDepthfOES,
+          (GLclampf depth),
+          (depth))
+
+API_ENTRY(glPointSizePointerOES,
+          (GLenum type, GLsizei stride, const GLvoid *pointer),
+          (type, stride, pointer))
+
+API_ENTRY(glTexGenfOES,
+          (GLenum coord, GLenum pname, GLfloat param),
+          (coord, pname, param))
+
+API_ENTRY(glTexGenfvOES,
+          (GLenum coord, GLenum pname, const GLfloat *params),
+          (coord, pname, params))
+
+API_ENTRY(glTexGeniOES,
+          (GLenum coord, GLenum pname, GLint param),
+          (coord, pname, param))
+
+API_ENTRY(glTexGenivOES,
+          (GLenum coord, GLenum pname, const GLint *params),
+          (coord, pname, params))
+
+API_ENTRY(glTexGenxOES,
+          (GLenum coord, GLenum pname, GLfixed param),
+          (coord, pname, param))
+
+API_ENTRY(glTexGenxvOES,
+          (GLenum coord, GLenum pname, const GLfixed *params),
+          (coord, pname, params))
+
+API_ENTRY(glGetTexGenfvOES,
+          (GLenum coord, GLenum pname, GLfloat *params),
+          (coord, pname, params))
+
+API_ENTRY(glGetTexGenivOES,
+          (GLenum coord, GLenum pname, GLint *params),
+          (coord, pname, params))
+
+API_ENTRY(glGetTexGenxvOES,
+          (GLenum coord, GLenum pname, GLfixed *params),
+          (coord, pname, params))
+
+API_ENTRY_RET(GLboolean,
+              glIsRenderbufferOES,
+              (GLuint renderbuffer),
+              (renderbuffer))
+
+API_ENTRY(glBindRenderbufferOES,
+          (GLenum target, GLuint renderbuffer),
+          (target, renderbuffer))
+
+API_ENTRY(glDeleteRenderbuffersOES,
+          (GLsizei n, const GLuint* renderbuffers),
+          (n, renderbuffers))
+
+API_ENTRY(glGenRenderbuffersOES,
+          (GLsizei n, GLuint* renderbuffers),
+          (n, renderbuffers))
+
+API_ENTRY(glRenderbufferStorageOES,
+          (GLenum target, GLenum internalformat, GLsizei width, GLsizei height),
+          (target, internalformat, width, height))
+
+API_ENTRY(glGetRenderbufferParameterivOES,
+          (GLenum target, GLenum pname, GLint* params),
+          (target, pname, params))
+
+API_ENTRY_RET(GLboolean,
+              glIsFramebufferOES,
+              (GLuint framebuffer),
+              (framebuffer))
+
+API_ENTRY(glBindFramebufferOES,
+          (GLenum target, GLuint framebuffer),
+          (target, framebuffer))
+
+API_ENTRY(glDeleteFramebuffersOES,
+          (GLsizei n, const GLuint* framebuffers),
+          (n, framebuffers))
+
+API_ENTRY(glGenFramebuffersOES,
+          (GLsizei n, GLuint* framebuffers),
+          (n, framebuffers))
+
+API_ENTRY_RET(GLenum,
+              glCheckFramebufferStatusOES,
+              (GLenum target),
+              (target))
+
+API_ENTRY(glFramebufferTexture2DOES,
+          (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level),
+          (target, attachment, textarget, texture, level))
+
+API_ENTRY(glFramebufferRenderbufferOES,
+          (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer),
+          (target, attachment, renderbuffertarget, renderbuffer))
+
+API_ENTRY(glGetFramebufferAttachmentParameterivOES,
+          (GLenum target, GLenum attachment, GLenum pname, GLint* params),
+          (target, attachment, pname, params))
+
+API_ENTRY(glGenerateMipmapOES,
+          (GLenum target),
+          (target))
+
+API_ENTRY(glDrawTexsOES,
+          (GLshort x, GLshort y, GLshort z, GLshort width, GLshort height),
+          (x, y, z, width, height))
+
+API_ENTRY(glDrawTexiOES,
+          (GLint x, GLint y, GLint z, GLint width, GLint height),
+          (x, y, z, width, height))
+
+API_ENTRY(glDrawTexfOES,
+          (GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height),
+          (x, y, z, width, height))
+
+API_ENTRY(glDrawTexxOES,
+          (GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height),
+          (x, y, z, width, height))
+
+API_ENTRY(glDrawTexsvOES,
+          (const GLshort *coords),
+          (coords))
+
+API_ENTRY(glDrawTexivOES,
+          (const GLint *coords),
+          (coords))
+
+API_ENTRY(glDrawTexfvOES,
+          (const GLfloat *coords),
+          (coords))
+
+API_ENTRY(glDrawTexxvOES,
+          (const GLfixed *coords),
+          (coords))
diff --git a/opengl/system/egl/egl.cfg b/opengl/system/egl/egl.cfg
new file mode 100644
index 0000000..9d3f2dc
--- /dev/null
+++ b/opengl/system/egl/egl.cfg
@@ -0,0 +1 @@
+0 0 emulation
diff --git a/opengl/system/egl/egl.cpp b/opengl/system/egl/egl.cpp
new file mode 100644
index 0000000..da89c4d
--- /dev/null
+++ b/opengl/system/egl/egl.cpp
@@ -0,0 +1,1254 @@
+/*
+* Copyright (C) 2011 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.
+*/
+
+#include "HostConnection.h"
+#include "ThreadInfo.h"
+#include "eglDisplay.h"
+#include "egl_ftable.h"
+#include <cutils/log.h>
+#include "gralloc_cb.h"
+#include "GLClientState.h"
+#include "GLSharedGroup.h"
+#include "eglContext.h"
+#include "ClientAPIExts.h"
+
+#include "GLEncoder.h"
+#ifdef WITH_GLES2
+#include "GL2Encoder.h"
+#endif
+
+#include <system/window.h>
+
+template<typename T>
+static T setErrorFunc(GLint error, T returnValue) {
+    getEGLThreadInfo()->eglError = error;
+    return returnValue;
+}
+
+const char *  eglStrError(EGLint err)
+{
+    switch (err){
+        case EGL_SUCCESS:           return "EGL_SUCCESS";
+        case EGL_NOT_INITIALIZED:   return "EGL_NOT_INITIALIZED";
+        case EGL_BAD_ACCESS:        return "EGL_BAD_ACCESS";
+        case EGL_BAD_ALLOC:         return "EGL_BAD_ALLOC";
+        case EGL_BAD_ATTRIBUTE:     return "EGL_BAD_ATTRIBUTE";
+        case EGL_BAD_CONFIG:        return "EGL_BAD_CONFIG";
+        case EGL_BAD_CONTEXT:       return "EGL_BAD_CONTEXT";
+        case EGL_BAD_CURRENT_SURFACE: return "EGL_BAD_CURRENT_SURFACE";
+        case EGL_BAD_DISPLAY:       return "EGL_BAD_DISPLAY";
+        case EGL_BAD_MATCH:         return "EGL_BAD_MATCH";
+        case EGL_BAD_NATIVE_PIXMAP: return "EGL_BAD_NATIVE_PIXMAP";
+        case EGL_BAD_NATIVE_WINDOW: return "EGL_BAD_NATIVE_WINDOW";
+        case EGL_BAD_PARAMETER:     return "EGL_BAD_PARAMETER";
+        case EGL_BAD_SURFACE:       return "EGL_BAD_SURFACE";
+        case EGL_CONTEXT_LOST:      return "EGL_CONTEXT_LOST";
+        default: return "UNKNOWN";
+    }
+}
+
+#define LOG_EGL_ERRORS 1
+
+#ifdef LOG_EGL_ERRORS
+
+#define setErrorReturn(error, retVal)     \
+    {                                                \
+        ALOGE("tid %d: %s(%d): error 0x%x (%s)", gettid(), __FUNCTION__, __LINE__, error, eglStrError(error));     \
+        return setErrorFunc(error, retVal);            \
+    }
+
+#define RETURN_ERROR(ret,err)           \
+    ALOGE("tid %d: %s(%d): error 0x%x (%s)", gettid(), __FUNCTION__, __LINE__, err, eglStrError(err));    \
+    getEGLThreadInfo()->eglError = err;    \
+    return ret;
+
+#else //!LOG_EGL_ERRORS
+
+#define setErrorReturn(error, retVal) return setErrorFunc(error, retVal);
+
+#define RETURN_ERROR(ret,err)           \
+    getEGLThreadInfo()->eglError = err; \
+    return ret;
+
+#endif //LOG_EGL_ERRORS
+
+#define VALIDATE_CONFIG(cfg,ret) \
+    if(((int)cfg<0)||((int)cfg>s_display.getNumConfigs())) { \
+        RETURN_ERROR(ret,EGL_BAD_CONFIG); \
+    }
+
+#define VALIDATE_DISPLAY(dpy,ret) \
+    if ((dpy) != (EGLDisplay)&s_display) { \
+        RETURN_ERROR(ret, EGL_BAD_DISPLAY);    \
+    }
+
+#define VALIDATE_DISPLAY_INIT(dpy,ret) \
+    VALIDATE_DISPLAY(dpy, ret)    \
+    if (!s_display.initialized()) {        \
+        RETURN_ERROR(ret, EGL_NOT_INITIALIZED);    \
+    }
+
+#define DEFINE_HOST_CONNECTION \
+    HostConnection *hostCon = HostConnection::get(); \
+    renderControl_encoder_context_t *rcEnc = (hostCon ? hostCon->rcEncoder() : NULL)
+
+#define DEFINE_AND_VALIDATE_HOST_CONNECTION(ret) \
+    HostConnection *hostCon = HostConnection::get(); \
+    if (!hostCon) { \
+        ALOGE("egl: Failed to get host connection\n"); \
+        return ret; \
+    } \
+    renderControl_encoder_context_t *rcEnc = hostCon->rcEncoder(); \
+    if (!rcEnc) { \
+        ALOGE("egl: Failed to get renderControl encoder context\n"); \
+        return ret; \
+    }
+
+#define VALIDATE_CONTEXT_RETURN(context,ret)        \
+    if (!context) {                                    \
+        RETURN_ERROR(ret,EGL_BAD_CONTEXT);    \
+    }
+
+#define VALIDATE_SURFACE_RETURN(surface, ret)    \
+    if (surface != EGL_NO_SURFACE) {    \
+        egl_surface_t* s( static_cast<egl_surface_t*>(surface) );    \
+        if (s->dpy != (EGLDisplay)&s_display)    \
+            setErrorReturn(EGL_BAD_DISPLAY, EGL_FALSE);    \
+    }
+
+
+EGLContext_t::EGLContext_t(EGLDisplay dpy, EGLConfig config, EGLContext_t* shareCtx) :
+    dpy(dpy),
+    config(config),
+    read(EGL_NO_SURFACE),
+    draw(EGL_NO_SURFACE),
+    shareCtx(shareCtx),
+    rcContext(0),
+    versionString(NULL),
+    vendorString(NULL),
+    rendererString(NULL),
+    extensionString(NULL)
+{
+    flags = 0;
+    version = 1;
+    clientState = new GLClientState();
+    if (shareCtx)
+        sharedGroup = shareCtx->getSharedGroup();
+    else
+        sharedGroup = GLSharedGroupPtr(new GLSharedGroup());
+};
+
+EGLContext_t::~EGLContext_t()
+{
+    delete clientState;
+    delete [] versionString;
+    delete [] vendorString;
+    delete [] rendererString;
+    delete [] extensionString;
+}
+
+// ----------------------------------------------------------------------------
+//egl_surface_t
+
+//we don't need to handle depth since it's handled when window created on the host
+
+struct egl_surface_t {
+
+    EGLDisplay          dpy;
+    EGLConfig           config;
+
+
+    egl_surface_t(EGLDisplay dpy, EGLConfig config, EGLint surfaceType);
+    virtual     ~egl_surface_t();
+
+    virtual     void        setSwapInterval(int interval) = 0;
+    virtual     EGLBoolean  swapBuffers() = 0;
+
+    EGLint      getSwapBehavior() const;
+    uint32_t    getRcSurface()   { return rcSurface; }
+    EGLint      getSurfaceType() { return surfaceType; }
+
+    EGLint      getWidth(){ return width; }
+    EGLint      getHeight(){ return height; }
+    void        setTextureFormat(EGLint _texFormat) { texFormat = _texFormat; }
+    EGLint      getTextureFormat() { return texFormat; }
+    void        setTextureTarget(EGLint _texTarget) { texTarget = _texTarget; }
+    EGLint      getTextureTarget() { return texTarget; }
+
+private:
+    //
+    //Surface attributes
+    //
+    EGLint      width;
+    EGLint      height;
+    EGLint      texFormat;
+    EGLint      texTarget;
+
+protected:
+    void        setWidth(EGLint w)  { width = w;  }
+    void        setHeight(EGLint h) { height = h; }
+
+    EGLint      surfaceType;
+    uint32_t    rcSurface; //handle to surface created via remote control
+};
+
+egl_surface_t::egl_surface_t(EGLDisplay dpy, EGLConfig config, EGLint surfaceType)
+    : dpy(dpy), config(config), surfaceType(surfaceType), rcSurface(0)
+{
+    width = 0;
+    height = 0;
+    texFormat = EGL_NO_TEXTURE;
+    texTarget = EGL_NO_TEXTURE;
+}
+
+EGLint egl_surface_t::getSwapBehavior() const {
+    return EGL_BUFFER_PRESERVED;
+}
+
+egl_surface_t::~egl_surface_t()
+{
+}
+
+// ----------------------------------------------------------------------------
+// egl_window_surface_t
+
+struct egl_window_surface_t : public egl_surface_t {
+    static egl_window_surface_t* create(
+            EGLDisplay dpy, EGLConfig config, EGLint surfType,
+            ANativeWindow* window);
+
+    virtual ~egl_window_surface_t();
+
+    virtual void       setSwapInterval(int interval);
+    virtual EGLBoolean swapBuffers();
+
+private:
+    egl_window_surface_t(
+            EGLDisplay dpy, EGLConfig config, EGLint surfType,
+            ANativeWindow* window);
+    EGLBoolean init();
+
+    ANativeWindow*              nativeWindow;
+    android_native_buffer_t*    buffer;
+};
+
+egl_window_surface_t::egl_window_surface_t (
+        EGLDisplay dpy, EGLConfig config, EGLint surfType,
+        ANativeWindow* window)
+:   egl_surface_t(dpy, config, surfType),
+    nativeWindow(window),
+    buffer(NULL)
+{
+    // keep a reference on the window
+    nativeWindow->common.incRef(&nativeWindow->common);
+    EGLint w,h;
+    nativeWindow->query(nativeWindow, NATIVE_WINDOW_WIDTH, &w);
+    setWidth(w);
+    nativeWindow->query(nativeWindow, NATIVE_WINDOW_HEIGHT, &h);
+    setHeight(h);
+}
+
+EGLBoolean egl_window_surface_t::init()
+{
+    if (nativeWindow->dequeueBuffer_DEPRECATED(nativeWindow, &buffer) != NO_ERROR) {
+        setErrorReturn(EGL_BAD_ALLOC, EGL_FALSE);
+    }
+
+    DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
+    rcSurface = rcEnc->rcCreateWindowSurface(rcEnc, (uint32_t)config,
+            getWidth(), getHeight());
+    if (!rcSurface) {
+        ALOGE("rcCreateWindowSurface returned 0");
+        return EGL_FALSE;
+    }
+    rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface,
+            ((cb_handle_t*)(buffer->handle))->hostHandle);
+
+    return EGL_TRUE;
+}
+
+egl_window_surface_t* egl_window_surface_t::create(
+        EGLDisplay dpy, EGLConfig config, EGLint surfType,
+        ANativeWindow* window)
+{
+    egl_window_surface_t* wnd = new egl_window_surface_t(
+            dpy, config, surfType, window);
+    if (wnd && !wnd->init()) {
+        delete wnd;
+        wnd = NULL;
+    }
+    return wnd;
+}
+
+egl_window_surface_t::~egl_window_surface_t() {
+    DEFINE_HOST_CONNECTION;
+    if (rcSurface && rcEnc) {
+        rcEnc->rcDestroyWindowSurface(rcEnc, rcSurface);
+    }
+    if (buffer) {
+        nativeWindow->cancelBuffer_DEPRECATED(nativeWindow, buffer);
+    }
+    nativeWindow->common.decRef(&nativeWindow->common);
+}
+
+void egl_window_surface_t::setSwapInterval(int interval)
+{
+    nativeWindow->setSwapInterval(nativeWindow, interval);
+}
+
+EGLBoolean egl_window_surface_t::swapBuffers()
+{
+    DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
+
+    rcEnc->rcFlushWindowColorBuffer(rcEnc, rcSurface);
+
+    nativeWindow->queueBuffer_DEPRECATED(nativeWindow, buffer);
+    if (nativeWindow->dequeueBuffer_DEPRECATED(nativeWindow, &buffer)) {
+        buffer = NULL;
+        setErrorReturn(EGL_BAD_ALLOC, EGL_FALSE);
+    }
+
+    rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface,
+            ((cb_handle_t *)(buffer->handle))->hostHandle);
+
+    return EGL_TRUE;
+}
+
+// ----------------------------------------------------------------------------
+//egl_pbuffer_surface_t
+
+struct egl_pbuffer_surface_t : public egl_surface_t {
+    static egl_pbuffer_surface_t* create(EGLDisplay dpy, EGLConfig config,
+            EGLint surfType, int32_t w, int32_t h, GLenum pixelFormat);
+
+    virtual ~egl_pbuffer_surface_t();
+
+    virtual void       setSwapInterval(int interval) {}
+    virtual EGLBoolean swapBuffers() { return EGL_TRUE; }
+
+    uint32_t getRcColorBuffer() { return rcColorBuffer; }
+
+private:
+    egl_pbuffer_surface_t(EGLDisplay dpy, EGLConfig config, EGLint surfType,
+            int32_t w, int32_t h);
+    EGLBoolean init(GLenum format);
+
+    uint32_t rcColorBuffer;
+};
+
+egl_pbuffer_surface_t::egl_pbuffer_surface_t(EGLDisplay dpy, EGLConfig config,
+        EGLint surfType, int32_t w, int32_t h)
+:   egl_surface_t(dpy, config, surfType),
+    rcColorBuffer(0)
+{
+    setWidth(w);
+    setHeight(h);
+}
+
+egl_pbuffer_surface_t::~egl_pbuffer_surface_t()
+{
+    DEFINE_HOST_CONNECTION;
+    if (rcEnc) {
+        if (rcColorBuffer) rcEnc->rcCloseColorBuffer(rcEnc, rcColorBuffer);
+        if (rcSurface)     rcEnc->rcDestroyWindowSurface(rcEnc, rcSurface);
+    }
+}
+
+EGLBoolean egl_pbuffer_surface_t::init(GLenum pixelFormat)
+{
+    DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
+
+    rcSurface = rcEnc->rcCreateWindowSurface(rcEnc, (uint32_t)config,
+            getWidth(), getHeight());
+    if (!rcSurface) {
+        ALOGE("rcCreateWindowSurface returned 0");
+        return EGL_FALSE;
+    }
+
+    rcColorBuffer = rcEnc->rcCreateColorBuffer(rcEnc, getWidth(), getHeight(),
+            pixelFormat);
+    if (!rcColorBuffer) {
+        ALOGE("rcCreateColorBuffer returned 0");
+        return EGL_FALSE;
+    }
+
+    rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface, rcColorBuffer);
+
+    return EGL_TRUE;
+}
+
+egl_pbuffer_surface_t* egl_pbuffer_surface_t::create(EGLDisplay dpy,
+        EGLConfig config, EGLint surfType, int32_t w, int32_t h,
+        GLenum pixelFormat)
+{
+    egl_pbuffer_surface_t* pb = new egl_pbuffer_surface_t(dpy, config, surfType,
+            w, h);
+    if (pb && !pb->init(pixelFormat)) {
+        delete pb;
+        pb = NULL;
+    }
+    return pb;
+}
+
+static const char *getGLString(int glEnum)
+{
+    EGLThreadInfo *tInfo = getEGLThreadInfo();
+    if (!tInfo || !tInfo->currentContext) {
+        return NULL;
+    }
+
+    const char** strPtr = NULL;
+
+#define GL_VENDOR                         0x1F00
+#define GL_RENDERER                       0x1F01
+#define GL_VERSION                        0x1F02
+#define GL_EXTENSIONS                     0x1F03
+
+    switch(glEnum) {
+        case GL_VERSION:
+            strPtr = &tInfo->currentContext->versionString;
+            break;
+        case GL_VENDOR:
+            strPtr = &tInfo->currentContext->vendorString;
+            break;
+        case GL_RENDERER:
+            strPtr = &tInfo->currentContext->rendererString;
+            break;
+        case GL_EXTENSIONS:
+            strPtr = &tInfo->currentContext->extensionString;
+            break;
+    }
+
+    if (!strPtr) {
+        return NULL;
+    }
+
+    if (*strPtr != NULL) {
+        //
+        // string is already cached
+        //
+        return *strPtr;
+    }
+
+    //
+    // first query of that string - need to query host
+    //
+    DEFINE_AND_VALIDATE_HOST_CONNECTION(NULL);
+    char *hostStr = NULL;
+    int n = rcEnc->rcGetGLString(rcEnc, glEnum, NULL, 0);
+    if (n < 0) {
+        hostStr = new char[-n+1];
+        n = rcEnc->rcGetGLString(rcEnc, glEnum, hostStr, -n);
+        if (n <= 0) {
+            delete [] hostStr;
+            hostStr = NULL;
+        }
+    }
+
+    //
+    // keep the string in the context and return its value
+    //
+    *strPtr = hostStr;
+    return hostStr;
+}
+
+// ----------------------------------------------------------------------------
+
+// The one and only supported display object.
+static eglDisplay s_display;
+
+static EGLClient_eglInterface s_eglIface = {
+    getThreadInfo: getEGLThreadInfo,
+    getGLString: getGLString
+};
+
+#define DBG_FUNC DBG("%s\n", __FUNCTION__)
+EGLDisplay eglGetDisplay(EGLNativeDisplayType display_id)
+{
+    //
+    // we support only EGL_DEFAULT_DISPLAY.
+    //
+    if (display_id != EGL_DEFAULT_DISPLAY) {
+        return EGL_NO_DISPLAY;
+    }
+
+    return (EGLDisplay)&s_display;
+}
+
+EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
+{
+    VALIDATE_DISPLAY(dpy,EGL_FALSE);
+
+    if (!s_display.initialize(&s_eglIface)) {
+        return EGL_FALSE;
+    }
+    if (major!=NULL)
+        *major = s_display.getVersionMajor();
+    if (minor!=NULL)
+        *minor = s_display.getVersionMinor();
+    return EGL_TRUE;
+}
+
+EGLBoolean eglTerminate(EGLDisplay dpy)
+{
+    VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
+
+    s_display.terminate();
+    return EGL_TRUE;
+}
+
+EGLint eglGetError()
+{
+    EGLint error = getEGLThreadInfo()->eglError;
+    getEGLThreadInfo()->eglError = EGL_SUCCESS;
+    return error;
+}
+
+__eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname)
+{
+    // search in EGL function table
+    for (int i=0; i<egl_num_funcs; i++) {
+        if (!strcmp(egl_funcs_by_name[i].name, procname)) {
+            return (__eglMustCastToProperFunctionPointerType)egl_funcs_by_name[i].proc;
+        }
+    }
+
+    //
+    // Make sure display is initialized before searching in client APIs
+    //
+    if (!s_display.initialized()) {
+        if (!s_display.initialize(&s_eglIface)) {
+            return NULL;
+        }
+    }
+
+    // look in gles client api's extensions table
+    return (__eglMustCastToProperFunctionPointerType)ClientAPIExts::getProcAddress(procname);
+
+    // Fail - function not found.
+    return NULL;
+}
+
+const char* eglQueryString(EGLDisplay dpy, EGLint name)
+{
+    VALIDATE_DISPLAY_INIT(dpy, NULL);
+
+    return s_display.queryString(name);
+}
+
+EGLBoolean eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
+{
+    VALIDATE_DISPLAY_INIT(dpy, NULL);
+
+    if(!num_config) {
+        RETURN_ERROR(EGL_FALSE,EGL_BAD_PARAMETER);
+    }
+
+    GLint numConfigs = s_display.getNumConfigs();
+    if (!configs) {
+        *num_config = numConfigs;
+        return EGL_TRUE;
+    }
+
+    int i=0;
+    for (i=0 ; i<numConfigs && i<config_size ; i++) {
+        *configs++ = (EGLConfig)i;
+    }
+    *num_config = i;
+    return EGL_TRUE;
+}
+
+EGLBoolean eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
+{
+    VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
+
+    int attribs_size = 0;
+    if (attrib_list) {
+        const EGLint * attrib_p = attrib_list;
+        while (attrib_p[0] != EGL_NONE) {
+            attribs_size += 2;
+            attrib_p += 2;
+        }
+        attribs_size++; //for the terminating EGL_NONE
+    }
+
+    DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
+    *num_config = rcEnc->rcChooseConfig(rcEnc, (EGLint*)attrib_list, attribs_size * sizeof(EGLint), (uint32_t*)configs, config_size);
+
+    return EGL_TRUE;
+}
+
+EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
+{
+    VALIDATE_DISPLAY_INIT(dpy, NULL);
+    VALIDATE_CONFIG(config, EGL_FALSE);
+
+    if (s_display.getConfigAttrib(config, attribute, value))
+    {
+        return EGL_TRUE;
+    }
+    else
+    {
+        RETURN_ERROR(EGL_FALSE, EGL_BAD_ATTRIBUTE);
+    }
+}
+
+EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list)
+{
+    VALIDATE_DISPLAY_INIT(dpy, NULL);
+    VALIDATE_CONFIG(config, EGL_FALSE);
+    if (win == 0) {
+        setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE);
+    }
+
+    EGLint surfaceType;
+    if (s_display.getConfigAttrib(config, EGL_SURFACE_TYPE, &surfaceType) == EGL_FALSE)    return EGL_FALSE;
+
+    if (!(surfaceType & EGL_WINDOW_BIT)) {
+        setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE);
+    }
+
+    if (static_cast<ANativeWindow*>(win)->common.magic != ANDROID_NATIVE_WINDOW_MAGIC) {
+        setErrorReturn(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
+    }
+
+    egl_surface_t* surface = egl_window_surface_t::create(
+            &s_display, config, surfaceType, static_cast<ANativeWindow*>(win));
+    if (!surface) {
+        setErrorReturn(EGL_BAD_ALLOC, EGL_NO_SURFACE);
+    }
+
+    return surface;
+}
+
+EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
+{
+    VALIDATE_DISPLAY_INIT(dpy, NULL);
+    VALIDATE_CONFIG(config, EGL_FALSE);
+
+    EGLint surfaceType;
+    if (s_display.getConfigAttrib(config, EGL_SURFACE_TYPE, &surfaceType) == EGL_FALSE)    return EGL_FALSE;
+
+    if (!(surfaceType & EGL_PBUFFER_BIT)) {
+        setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE);
+    }
+
+    int32_t w = 0;
+    int32_t h = 0;
+    EGLint texFormat = EGL_NO_TEXTURE;
+    EGLint texTarget = EGL_NO_TEXTURE;
+    while (attrib_list[0]) {
+        switch (attrib_list[0]) {
+            case EGL_WIDTH:
+                w = attrib_list[1];
+                break;
+            case EGL_HEIGHT:
+                h = attrib_list[1];
+                break;
+            case EGL_TEXTURE_FORMAT:
+                texFormat = attrib_list[1];
+                break;
+            case EGL_TEXTURE_TARGET:
+                texTarget = attrib_list[1];
+                break;
+            default:
+                break;
+        };
+        attrib_list+=2;
+    }
+    if (((texFormat == EGL_NO_TEXTURE)&&(texTarget != EGL_NO_TEXTURE)) ||
+        ((texFormat != EGL_NO_TEXTURE)&&(texTarget == EGL_NO_TEXTURE))) {
+        setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE);
+    }
+    // TODO: check EGL_TEXTURE_FORMAT - need to support eglBindTexImage
+
+    GLenum pixelFormat;
+    if (s_display.getConfigGLPixelFormat(config, &pixelFormat) == EGL_FALSE)
+        setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE);
+
+    egl_surface_t* surface = egl_pbuffer_surface_t::create(dpy, config,
+            surfaceType, w, h, pixelFormat);
+    if (!surface) {
+        setErrorReturn(EGL_BAD_ALLOC, EGL_NO_SURFACE);
+    }
+
+    //setup attributes
+    surface->setTextureFormat(texFormat);
+    surface->setTextureTarget(texTarget);
+
+    return surface;
+}
+
+EGLSurface eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
+{
+    //XXX: Pixmap not supported. The host cannot render to a pixmap resource
+    //     located on host. In order to support Pixmaps we should either punt
+    //     to s/w rendering -or- let the host render to a buffer that will be
+    //     copied back to guest at some sync point. None of those methods not
+    //     implemented and pixmaps are not used with OpenGL anyway ...
+    return EGL_NO_SURFACE;
+}
+
+EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface eglSurface)
+{
+    VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
+    VALIDATE_SURFACE_RETURN(eglSurface, EGL_FALSE);
+
+    egl_surface_t* surface(static_cast<egl_surface_t*>(eglSurface));
+    delete surface;
+
+    return EGL_TRUE;
+}
+
+EGLBoolean eglQuerySurface(EGLDisplay dpy, EGLSurface eglSurface, EGLint attribute, EGLint *value)
+{
+    VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
+    VALIDATE_SURFACE_RETURN(eglSurface, EGL_FALSE);
+
+    egl_surface_t* surface( static_cast<egl_surface_t*>(eglSurface) );
+    EGLBoolean ret = EGL_TRUE;
+    switch (attribute) {
+        case EGL_CONFIG_ID:
+            ret = s_display.getConfigAttrib(surface->config, EGL_CONFIG_ID, value);
+            break;
+        case EGL_WIDTH:
+            *value = surface->getWidth();
+            break;
+        case EGL_HEIGHT:
+            *value = surface->getHeight();
+            break;
+        case EGL_TEXTURE_FORMAT:
+            *value = surface->getTextureFormat();
+            break;
+        case EGL_TEXTURE_TARGET:
+            *value = surface->getTextureTarget();
+            break;
+        case EGL_SWAP_BEHAVIOR:
+            *value = surface->getSwapBehavior();
+            break;
+        case EGL_LARGEST_PBUFFER:
+            // not modified for a window or pixmap surface
+            // and we ignore it when creating a PBuffer surface (default is EGL_FALSE)
+            if (surface->getSurfaceType() & EGL_PBUFFER_BIT) *value = EGL_FALSE;
+            break;
+        //TODO: complete other attributes
+        default:
+            ALOGE("eglQuerySurface %x  EGL_BAD_ATTRIBUTE", attribute);
+            ret = setErrorFunc(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+            break;
+    }
+
+    return ret;
+}
+
+EGLBoolean eglBindAPI(EGLenum api)
+{
+    if (api != EGL_OPENGL_ES_API)
+        setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE);
+    return EGL_TRUE;
+}
+
+EGLenum eglQueryAPI()
+{
+    return EGL_OPENGL_ES_API;
+}
+
+EGLBoolean eglWaitClient()
+{
+    return eglWaitGL();
+}
+
+EGLBoolean eglReleaseThread()
+{
+    EGLThreadInfo *tInfo = getEGLThreadInfo();
+    if (tInfo && tInfo->currentContext) {
+        return eglMakeCurrent(&s_display, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE);
+    }
+    return EGL_TRUE;
+}
+
+EGLSurface eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)
+{
+    //TODO
+    ALOGW("%s not implemented", __FUNCTION__);
+    return 0;
+}
+
+EGLBoolean eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
+{
+    //TODO
+    ALOGW("%s not implemented", __FUNCTION__);
+    return 0;
+}
+
+EGLBoolean eglBindTexImage(EGLDisplay dpy, EGLSurface eglSurface, EGLint buffer)
+{
+    VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
+    VALIDATE_SURFACE_RETURN(eglSurface, EGL_FALSE);
+    if (eglSurface == EGL_NO_SURFACE) {
+        setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE);
+    }
+
+    if (buffer != EGL_BACK_BUFFER) {
+        setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE);
+    }
+
+    egl_surface_t* surface( static_cast<egl_surface_t*>(eglSurface) );
+
+    if (surface->getTextureFormat() == EGL_NO_TEXTURE) {
+        setErrorReturn(EGL_BAD_MATCH, EGL_FALSE);
+    }
+
+    if (!(surface->getSurfaceType() & EGL_PBUFFER_BIT)) {
+        setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE);
+    }
+
+    //It's now safe to cast to pbuffer surface
+    egl_pbuffer_surface_t* pbSurface = (egl_pbuffer_surface_t*)surface;
+
+    DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
+    rcEnc->rcBindTexture(rcEnc, pbSurface->getRcColorBuffer());
+
+    return GL_TRUE;
+}
+
+EGLBoolean eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+    //TODO
+    ALOGW("%s not implemented", __FUNCTION__);
+    return 0;
+}
+
+EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval)
+{
+    VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
+    DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
+
+    EGLContext_t* ctx = getEGLThreadInfo()->currentContext;
+    if (!ctx) {
+        setErrorReturn(EGL_BAD_CONTEXT, EGL_FALSE);
+    }
+    if (!ctx->draw) {
+        setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE);
+    }
+    egl_surface_t* draw(static_cast<egl_surface_t*>(ctx->draw));
+    draw->setSwapInterval(interval);
+
+    rcEnc->rcFBSetSwapInterval(rcEnc, interval); //TODO: implement on the host
+
+    return EGL_TRUE;
+}
+
+EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
+{
+    VALIDATE_DISPLAY_INIT(dpy, EGL_NO_CONTEXT);
+    VALIDATE_CONFIG(config, EGL_NO_CONTEXT);
+
+    EGLint version = 1; //default
+    while (attrib_list && attrib_list[0]) {
+        if (attrib_list[0] == EGL_CONTEXT_CLIENT_VERSION) version = attrib_list[1];
+        attrib_list+=2;
+    }
+
+    uint32_t rcShareCtx = 0;
+    EGLContext_t * shareCtx = NULL;
+    if (share_context) {
+        shareCtx = static_cast<EGLContext_t*>(share_context);
+        rcShareCtx = shareCtx->rcContext;
+        if (shareCtx->dpy != dpy)
+            setErrorReturn(EGL_BAD_MATCH, EGL_NO_CONTEXT);
+    }
+
+    DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_NO_CONTEXT);
+    uint32_t rcContext = rcEnc->rcCreateContext(rcEnc, (uint32_t)config, rcShareCtx, version);
+    if (!rcContext) {
+        ALOGE("rcCreateContext returned 0");
+        setErrorReturn(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
+    }
+
+    EGLContext_t * context = new EGLContext_t(dpy, config, shareCtx);
+    if (!context)
+        setErrorReturn(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
+
+    context->version = version;
+    context->rcContext = rcContext;
+
+
+    return context;
+}
+
+EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
+{
+    VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
+    VALIDATE_CONTEXT_RETURN(ctx, EGL_FALSE);
+
+    EGLContext_t * context = static_cast<EGLContext_t*>(ctx);
+
+    if (getEGLThreadInfo()->currentContext == context)
+    {
+        eglMakeCurrent(dpy, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE);
+    }
+
+    if (context->rcContext) {
+        DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
+        rcEnc->rcDestroyContext(rcEnc, context->rcContext);
+        context->rcContext = 0;
+    }
+
+    delete context;
+    return EGL_TRUE;
+}
+
+EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
+{
+    VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
+    VALIDATE_SURFACE_RETURN(draw, EGL_FALSE);
+    VALIDATE_SURFACE_RETURN(read, EGL_FALSE);
+
+    if ((read == EGL_NO_SURFACE && draw == EGL_NO_SURFACE) && (ctx != EGL_NO_CONTEXT))
+        setErrorReturn(EGL_BAD_MATCH, EGL_FALSE);
+    if ((read != EGL_NO_SURFACE || draw != EGL_NO_SURFACE) && (ctx == EGL_NO_CONTEXT))
+        setErrorReturn(EGL_BAD_MATCH, EGL_FALSE);
+
+    EGLContext_t * context = static_cast<EGLContext_t*>(ctx);
+    uint32_t ctxHandle = (context) ? context->rcContext : 0;
+    egl_surface_t * drawSurf = static_cast<egl_surface_t *>(draw);
+    uint32_t drawHandle = (drawSurf) ? drawSurf->getRcSurface() : 0;
+    egl_surface_t * readSurf = static_cast<egl_surface_t *>(read);
+    uint32_t readHandle = (readSurf) ? readSurf->getRcSurface() : 0;
+
+    //
+    // Nothing to do if no binding change has made
+    //
+    EGLThreadInfo *tInfo = getEGLThreadInfo();
+    if (tInfo->currentContext == context &&
+        (context == NULL ||
+        (context && context->draw == draw && context->read == read))) {
+        return EGL_TRUE;
+    }
+
+    if (context && (context->flags & EGLContext_t::IS_CURRENT) && (context != tInfo->currentContext)) {
+        //context is current to another thread
+        setErrorReturn(EGL_BAD_ACCESS, EGL_FALSE);
+    }
+
+    DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
+    if (rcEnc->rcMakeCurrent(rcEnc, ctxHandle, drawHandle, readHandle) == EGL_FALSE) {
+        ALOGE("rcMakeCurrent returned EGL_FALSE");
+        setErrorReturn(EGL_BAD_CONTEXT, EGL_FALSE);
+    }
+
+    //Now make the local bind
+    if (context) {
+        context->draw = draw;
+        context->read = read;
+        context->flags |= EGLContext_t::IS_CURRENT;
+        //set the client state
+        if (context->version == 2) {
+            hostCon->gl2Encoder()->setClientState(context->getClientState());
+            hostCon->gl2Encoder()->setSharedGroup(context->getSharedGroup());
+        }
+        else {
+            hostCon->glEncoder()->setClientState(context->getClientState());
+            hostCon->glEncoder()->setSharedGroup(context->getSharedGroup());
+        }
+    } 
+    else {
+        //release ClientState & SharedGroup
+        if (tInfo->currentContext->version == 2) {
+            hostCon->gl2Encoder()->setClientState(NULL);
+            hostCon->gl2Encoder()->setSharedGroup(GLSharedGroupPtr(NULL));
+        }
+        else {
+            hostCon->glEncoder()->setClientState(NULL);
+            hostCon->glEncoder()->setSharedGroup(GLSharedGroupPtr(NULL));
+        }
+
+    }
+
+    if (tInfo->currentContext)
+        tInfo->currentContext->flags &= ~EGLContext_t::IS_CURRENT;
+
+    //Now make current
+    tInfo->currentContext = context;
+
+    //Check maybe we need to init the encoder, if it's first eglMakeCurrent
+    if (tInfo->currentContext) {
+        if (tInfo->currentContext->version == 2) {
+            if (!hostCon->gl2Encoder()->isInitialized()) {
+                s_display.gles2_iface()->init();
+                hostCon->gl2Encoder()->setInitialized();
+                ClientAPIExts::initClientFuncs(s_display.gles2_iface(), 1);
+            }
+        }
+        else {
+            if (!hostCon->glEncoder()->isInitialized()) {
+                s_display.gles_iface()->init();
+                hostCon->glEncoder()->setInitialized();
+                ClientAPIExts::initClientFuncs(s_display.gles_iface(), 0);
+            }
+        }
+    }
+
+    return EGL_TRUE;
+}
+
+EGLContext eglGetCurrentContext()
+{
+    return getEGLThreadInfo()->currentContext;
+}
+
+EGLSurface eglGetCurrentSurface(EGLint readdraw)
+{
+    EGLContext_t * context = getEGLThreadInfo()->currentContext;
+    if (!context)
+        return EGL_NO_SURFACE; //not an error
+
+    switch (readdraw) {
+        case EGL_READ:
+            return context->read;
+        case EGL_DRAW:
+            return context->draw;
+        default:
+            setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
+    }
+}
+
+EGLDisplay eglGetCurrentDisplay()
+{
+    EGLContext_t * context = getEGLThreadInfo()->currentContext;
+    if (!context)
+        return EGL_NO_DISPLAY; //not an error
+
+    return context->dpy;
+}
+
+EGLBoolean eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
+{
+    VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
+    VALIDATE_CONTEXT_RETURN(ctx, EGL_FALSE);
+
+    EGLContext_t * context = static_cast<EGLContext_t*>(ctx);
+
+    EGLBoolean ret = EGL_TRUE;
+    switch (attribute) {
+        case EGL_CONFIG_ID:
+            ret = s_display.getConfigAttrib(context->config, EGL_CONFIG_ID, value);
+            break;
+        case EGL_CONTEXT_CLIENT_TYPE:
+            *value = EGL_OPENGL_ES_API;
+            break;
+        case EGL_CONTEXT_CLIENT_VERSION:
+            *value = context->version;
+            break;
+        case EGL_RENDER_BUFFER:
+            if (!context->draw)
+                *value = EGL_NONE;
+            else
+                *value = EGL_BACK_BUFFER; //single buffer not supported
+            break;
+        default:
+            ALOGE("eglQueryContext %x  EGL_BAD_ATTRIBUTE", attribute);
+            setErrorReturn(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+            break;
+    }
+
+    return ret;
+}
+
+EGLBoolean eglWaitGL()
+{
+    EGLThreadInfo *tInfo = getEGLThreadInfo();
+    if (!tInfo || !tInfo->currentContext) {
+        return EGL_FALSE;
+    }
+
+    if (tInfo->currentContext->version == 2) {
+        s_display.gles2_iface()->finish();
+    }
+    else {
+        s_display.gles_iface()->finish();
+    }
+
+    return EGL_TRUE;
+}
+
+EGLBoolean eglWaitNative(EGLint engine)
+{
+    return EGL_TRUE;
+}
+
+EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface eglSurface)
+{
+    VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
+    if (eglSurface == EGL_NO_SURFACE)
+        setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE);
+
+    DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
+
+    egl_surface_t* d = static_cast<egl_surface_t*>(eglSurface);
+    if (d->dpy != dpy)
+        setErrorReturn(EGL_BAD_DISPLAY, EGL_FALSE);
+
+    // post the surface
+    d->swapBuffers();
+
+    hostCon->flush();
+    return EGL_TRUE;
+}
+
+EGLBoolean eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
+{
+    //TODO :later
+    return 0;
+}
+
+EGLBoolean eglLockSurfaceKHR(EGLDisplay display, EGLSurface surface, const EGLint *attrib_list)
+{
+    //TODO later
+    return 0;
+}
+
+EGLBoolean eglUnlockSurfaceKHR(EGLDisplay display, EGLSurface surface)
+{
+    //TODO later
+    return 0;
+}
+
+EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)
+{
+    VALIDATE_DISPLAY_INIT(dpy, EGL_NO_IMAGE_KHR);
+    if (ctx != EGL_NO_CONTEXT) {
+        setErrorReturn(EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
+    }
+    if (target != EGL_NATIVE_BUFFER_ANDROID) {
+        setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
+    }
+
+    android_native_buffer_t* native_buffer = (android_native_buffer_t*)buffer;
+
+    if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC)
+        setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
+
+    if (native_buffer->common.version != sizeof(android_native_buffer_t))
+        setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
+
+    cb_handle_t *cb = (cb_handle_t *)(native_buffer->handle);
+
+    switch (cb->format) {
+        case HAL_PIXEL_FORMAT_RGBA_8888:
+        case HAL_PIXEL_FORMAT_RGBX_8888:
+        case HAL_PIXEL_FORMAT_RGB_888:
+        case HAL_PIXEL_FORMAT_RGB_565:
+        case HAL_PIXEL_FORMAT_BGRA_8888:
+        case HAL_PIXEL_FORMAT_RGBA_5551:
+        case HAL_PIXEL_FORMAT_RGBA_4444:
+            break;
+        default:
+            setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
+    }
+
+    native_buffer->common.incRef(&native_buffer->common);
+    return (EGLImageKHR)native_buffer;
+}
+
+EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img)
+{
+    VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
+    android_native_buffer_t* native_buffer = (android_native_buffer_t*)img;
+
+    if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC)
+        setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE);
+
+    if (native_buffer->common.version != sizeof(android_native_buffer_t))
+        setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE);
+
+    native_buffer->common.decRef(&native_buffer->common);
+
+    return EGL_TRUE;
+}
+
+#define FENCE_SYNC_HANDLE (EGLSyncKHR)0xFE4CE
+
+EGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, EGLenum type,
+        const EGLint *attrib_list)
+{
+    // TODO: This implementation could be faster. We should require the host EGL
+    // to support KHR_fence_sync, or at least pipe the fence command to the host
+    // and wait for it (probably involving a glFinish on the host) in
+    // eglClientWaitSyncKHR.
+
+    VALIDATE_DISPLAY(dpy, EGL_NO_SYNC_KHR);
+
+    if (type != EGL_SYNC_FENCE_KHR ||
+            (attrib_list != NULL && attrib_list[0] != EGL_NONE)) {
+        setErrorReturn(EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR);
+    }
+
+    EGLThreadInfo *tInfo = getEGLThreadInfo();
+    if (!tInfo || !tInfo->currentContext) {
+        setErrorReturn(EGL_BAD_MATCH, EGL_NO_SYNC_KHR);
+    }
+
+    if (tInfo->currentContext->version == 2) {
+        s_display.gles2_iface()->finish();
+    } else {
+        s_display.gles_iface()->finish();
+    }
+
+    return FENCE_SYNC_HANDLE;
+}
+
+EGLBoolean eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
+{
+    if (sync != FENCE_SYNC_HANDLE) {
+        setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE);
+    }
+
+    return EGL_TRUE;
+}
+
+EGLint eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags,
+        EGLTimeKHR timeout)
+{
+    if (sync != FENCE_SYNC_HANDLE) {
+        setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE);
+    }
+
+    return EGL_CONDITION_SATISFIED_KHR;
+}
+
+EGLBoolean eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync,
+        EGLint attribute, EGLint *value)
+{
+    if (sync != FENCE_SYNC_HANDLE) {
+        setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE);
+    }
+
+    switch (attribute) {
+    case EGL_SYNC_TYPE_KHR:
+        *value = EGL_SYNC_FENCE_KHR;
+        return EGL_TRUE;
+    case EGL_SYNC_STATUS_KHR:
+        *value = EGL_SIGNALED_KHR;
+        return EGL_TRUE;
+    case EGL_SYNC_CONDITION_KHR:
+        *value = EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR;
+        return EGL_TRUE;
+    default:
+        setErrorReturn(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+    }
+}
diff --git a/opengl/system/egl/eglContext.h b/opengl/system/egl/eglContext.h
new file mode 100644
index 0000000..2ca6d0c
--- /dev/null
+++ b/opengl/system/egl/eglContext.h
@@ -0,0 +1,51 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#ifndef _EGL_CONTEXT_H
+#define _EGL_CONTEXT_H
+
+#include "GLClientState.h"
+#include "GLSharedGroup.h"
+
+struct EGLContext_t {
+
+    enum {
+        IS_CURRENT      =   0x00010000,
+        NEVER_CURRENT   =   0x00020000
+    };
+
+    EGLContext_t(EGLDisplay dpy, EGLConfig config, EGLContext_t* shareCtx);
+    ~EGLContext_t();
+    uint32_t            flags;
+    EGLDisplay          dpy;
+    EGLConfig           config;
+    EGLSurface          read;
+    EGLSurface          draw;
+    EGLContext_t    *   shareCtx;
+    EGLint                version;
+    uint32_t             rcContext;
+    const char*         versionString;
+    const char*         vendorString;
+    const char*         rendererString;
+    const char*         extensionString;
+
+    GLClientState * getClientState(){ return clientState; }
+    GLSharedGroupPtr getSharedGroup(){ return sharedGroup; }
+private:
+    GLClientState    *    clientState;
+    GLSharedGroupPtr      sharedGroup;
+};
+
+#endif
diff --git a/opengl/system/egl/eglDisplay.cpp b/opengl/system/egl/eglDisplay.cpp
new file mode 100644
index 0000000..bcb0d4b
--- /dev/null
+++ b/opengl/system/egl/eglDisplay.cpp
@@ -0,0 +1,497 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#include "eglDisplay.h"
+#include "HostConnection.h"
+#include <dlfcn.h>
+
+static const int systemEGLVersionMajor = 1;
+static const int systemEGLVersionMinor = 4;
+static const char systemEGLVendor[] = "Google Android emulator";
+
+// list of extensions supported by this EGL implementation
+//  NOTE that each extension name should be suffixed with space
+static const char systemStaticEGLExtensions[] =
+            "EGL_ANDROID_image_native_buffer "
+            "EGL_KHR_fence_sync ";
+
+// list of extensions supported by this EGL implementation only if supported
+// on the host implementation.
+//  NOTE that each extension name should be suffixed with space
+static const char systemDynamicEGLExtensions[] =
+            "EGL_KHR_image_base "
+            "EGL_KHR_gl_texture_2d_image ";
+
+
+static void *s_gles_lib = NULL;
+static void *s_gles2_lib = NULL;
+
+// The following function will be called when we (libEGL)
+// gets unloaded
+// At this point we want to unload the gles libraries we
+// might have loaded during initialization
+static void __attribute__ ((destructor)) do_on_unload(void)
+{
+    if (s_gles_lib) {
+        dlclose(s_gles_lib);
+    }
+
+    if (s_gles2_lib) {
+        dlclose(s_gles2_lib);
+    }
+}
+
+eglDisplay::eglDisplay() :
+    m_initialized(false),
+    m_major(0),
+    m_minor(0),
+    m_hostRendererVersion(0),
+    m_numConfigs(0),
+    m_numConfigAttribs(0),
+    m_attribs(DefaultKeyedVector<EGLint, EGLint>(ATTRIBUTE_NONE)),
+    m_configs(NULL),
+    m_gles_iface(NULL),
+    m_gles2_iface(NULL),
+    m_versionString(NULL),
+    m_vendorString(NULL),
+    m_extensionString(NULL)
+{
+    pthread_mutex_init(&m_lock, NULL);
+}
+
+eglDisplay::~eglDisplay()
+{
+    pthread_mutex_destroy(&m_lock);
+}
+
+bool eglDisplay::initialize(EGLClient_eglInterface *eglIface)
+{
+    pthread_mutex_lock(&m_lock);
+    if (!m_initialized) {
+
+        //
+        // load GLES client API
+        //
+        m_gles_iface = loadGLESClientAPI("/system/lib/egl/libGLESv1_CM_emulation.so",
+                                         eglIface,
+                                         &s_gles_lib);
+        if (!m_gles_iface) {
+            pthread_mutex_unlock(&m_lock);
+            ALOGE("Failed to load gles1 iface");
+            return false;
+        }
+
+#ifdef WITH_GLES2
+        m_gles2_iface = loadGLESClientAPI("/system/lib/egl/libGLESv2_emulation.so",
+                                          eglIface,
+                                          &s_gles2_lib);
+        // Note that if loading gles2 failed, we can still run with no
+        // GLES2 support, having GLES2 is not mandatory.
+#endif
+
+        //
+        // establish connection with the host
+        //
+        HostConnection *hcon = HostConnection::get();
+        if (!hcon) {
+            pthread_mutex_unlock(&m_lock);
+            ALOGE("Failed to establish connection with the host\n");
+            return false;
+        }
+
+        //
+        // get renderControl encoder instance
+        //
+        renderControl_encoder_context_t *rcEnc = hcon->rcEncoder();
+        if (!rcEnc) {
+            pthread_mutex_unlock(&m_lock);
+            ALOGE("Failed to get renderControl encoder instance");
+            return false;
+        }
+
+        //
+        // Query host reneder and EGL version
+        //
+        m_hostRendererVersion = rcEnc->rcGetRendererVersion(rcEnc);
+        EGLint status = rcEnc->rcGetEGLVersion(rcEnc, &m_major, &m_minor);
+        if (status != EGL_TRUE) {
+            // host EGL initialization failed !!
+            pthread_mutex_unlock(&m_lock);
+            return false;
+        }
+
+        //
+        // Take minimum version beween what we support and what the host support
+        //
+        if (m_major > systemEGLVersionMajor) {
+            m_major = systemEGLVersionMajor;
+            m_minor = systemEGLVersionMinor;
+        }
+        else if (m_major == systemEGLVersionMajor &&
+                 m_minor > systemEGLVersionMinor) {
+            m_minor = systemEGLVersionMinor;
+        }
+
+        //
+        // Query the host for the set of configs
+        //
+        m_numConfigs = rcEnc->rcGetNumConfigs(rcEnc, (uint32_t*)&m_numConfigAttribs);
+        if (m_numConfigs <= 0 || m_numConfigAttribs <= 0) {
+            // just sanity check - should never happen
+            pthread_mutex_unlock(&m_lock);
+            return false;
+        }
+
+        uint32_t nInts = m_numConfigAttribs * (m_numConfigs + 1);
+        EGLint tmp_buf[nInts];
+        m_configs = new EGLint[nInts-m_numConfigAttribs];
+        if (!m_configs) {
+            pthread_mutex_unlock(&m_lock);
+            return false;
+        }
+
+        //EGLint n = rcEnc->rcGetConfigs(rcEnc, nInts*sizeof(EGLint), m_configs);
+        EGLint n = rcEnc->rcGetConfigs(rcEnc, nInts*sizeof(EGLint), (GLuint*)tmp_buf);
+        if (n != m_numConfigs) {
+            pthread_mutex_unlock(&m_lock);
+            return false;
+        }
+
+        //Fill the attributes vector.
+        //The first m_numConfigAttribs values of tmp_buf are the actual attributes enums.
+        for (int i=0; i<m_numConfigAttribs; i++) {
+            m_attribs.add(tmp_buf[i], i);
+        }
+
+        //Copy the actual configs data to m_configs
+        memcpy(m_configs, tmp_buf + m_numConfigAttribs, m_numConfigs*m_numConfigAttribs*sizeof(EGLint));
+
+        m_initialized = true;
+    }
+    pthread_mutex_unlock(&m_lock);
+
+    processConfigs();
+
+    return true;
+}
+
+void eglDisplay::processConfigs()
+{
+    for (int i=0; i<m_numConfigs; i++) {
+        EGLConfig config = (EGLConfig)i;
+        //Setup the EGL_NATIVE_VISUAL_ID attribute
+        PixelFormat format;
+        if (getConfigNativePixelFormat(config, &format)) {
+            setConfigAttrib(config, EGL_NATIVE_VISUAL_ID, format);
+        }
+    }
+}
+
+void eglDisplay::terminate()
+{
+    pthread_mutex_lock(&m_lock);
+    if (m_initialized) {
+        m_initialized = false;
+        delete [] m_configs;
+        m_configs = NULL;
+
+        if (m_versionString) {
+            free(m_versionString);
+            m_versionString = NULL;
+        }
+        if (m_vendorString) {
+            free(m_vendorString);
+            m_vendorString = NULL;
+        }
+        if (m_extensionString) {
+            free(m_extensionString);
+            m_extensionString = NULL;
+        }
+    }
+    pthread_mutex_unlock(&m_lock);
+}
+
+EGLClient_glesInterface *eglDisplay::loadGLESClientAPI(const char *libName,
+                                                       EGLClient_eglInterface *eglIface,
+                                                       void **libHandle)
+{
+    void *lib = dlopen(libName, RTLD_NOW);
+    if (!lib) {
+        ALOGE("Failed to dlopen %s", libName);
+        return NULL;
+    }
+
+    init_emul_gles_t init_gles_func = (init_emul_gles_t)dlsym(lib,"init_emul_gles");
+    if (!init_gles_func) {
+        ALOGE("Failed to find init_emul_gles");
+        dlclose((void*)lib);
+        return NULL;
+    }
+
+    *libHandle = lib;
+    return (*init_gles_func)(eglIface);
+}
+
+static char *queryHostEGLString(EGLint name)
+{
+    HostConnection *hcon = HostConnection::get();
+    if (hcon) {
+        renderControl_encoder_context_t *rcEnc = hcon->rcEncoder();
+        if (rcEnc) {
+            int n = rcEnc->rcQueryEGLString(rcEnc, name, NULL, 0);
+            if (n < 0) {
+                // allocate space for the string with additional
+                // space charachter to be suffixed at the end.
+                char *str = (char *)malloc(-n+2);
+                n = rcEnc->rcQueryEGLString(rcEnc, name, str, -n);
+                if (n > 0) {
+                    // add extra space at end of string which will be
+                    // needed later when filtering the extension list.
+                    strcat(str, " ");
+                    return str;
+                }
+
+                free(str);
+            }
+        }
+    }
+
+    return NULL;
+}
+
+static bool findExtInList(const char* token, int tokenlen, const char* list)
+{
+    const char* p = list;
+    while (*p != '\0') {
+        const char* q = strchr(p, ' ');
+        if (q == NULL) {
+            /* should not happen, list must be space-terminated */
+            break;
+        }
+        if (tokenlen == (q - p) && !memcmp(token, p, tokenlen)) {
+            return true;  /* found it */
+        }
+        p = q+1;
+    }
+    return false;  /* not found */
+}
+
+static char *buildExtensionString()
+{
+    //Query host extension string
+    char *hostExt = queryHostEGLString(EGL_EXTENSIONS);
+    if (!hostExt || (hostExt[1] == '\0')) {
+        // no extensions on host - only static extension list supported
+        return strdup(systemStaticEGLExtensions);
+    }
+
+    //
+    // Filter host extension list to include only extensions
+    // we can support (in the systemDynamicEGLExtensions list)
+    //
+    char *ext = (char *)hostExt;
+    char *c = ext;
+    char *insert = ext;
+    while(*c != '\0') {
+        if (*c == ' ') {
+            int len = c - ext;
+            if (findExtInList(ext, len, systemDynamicEGLExtensions)) {
+                if (ext != insert) {
+                    memcpy(insert, ext, len+1); // including space
+                }
+                insert += (len + 1);
+            }
+            ext = c + 1;
+        }
+        c++;
+    }
+    *insert = '\0';
+
+    int n = strlen(hostExt);
+    if (n > 0) {
+        char *str;
+        asprintf(&str,"%s%s", systemStaticEGLExtensions, hostExt);
+        free((char*)hostExt);
+        return str;
+    }
+    else {
+        free((char*)hostExt);
+        return strdup(systemStaticEGLExtensions);
+    }
+}
+
+const char *eglDisplay::queryString(EGLint name)
+{
+    if (name == EGL_CLIENT_APIS) {
+        return "OpenGL_ES";
+    }
+    else if (name == EGL_VERSION) {
+        pthread_mutex_lock(&m_lock);
+        if (m_versionString) {
+            pthread_mutex_unlock(&m_lock);
+            return m_versionString;
+        }
+
+        // build version string
+        asprintf(&m_versionString, "%d.%d", m_major, m_minor);
+        pthread_mutex_unlock(&m_lock);
+
+        return m_versionString;
+    }
+    else if (name == EGL_VENDOR) {
+        pthread_mutex_lock(&m_lock);
+        if (m_vendorString) {
+            pthread_mutex_unlock(&m_lock);
+            return m_vendorString;
+        }
+
+        // build vendor string
+        const char *hostVendor = queryHostEGLString(EGL_VENDOR);
+
+        if (hostVendor) {
+            asprintf(&m_vendorString, "%s Host: %s",
+                                     systemEGLVendor, hostVendor);
+            free((char*)hostVendor);
+        }
+        else {
+            m_vendorString = (char *)systemEGLVendor;
+        }
+        pthread_mutex_unlock(&m_lock);
+
+        return m_vendorString;
+    }
+    else if (name == EGL_EXTENSIONS) {
+        pthread_mutex_lock(&m_lock);
+        if (m_extensionString) {
+            pthread_mutex_unlock(&m_lock);
+            return m_extensionString;
+        }
+
+        // build extension string
+        m_extensionString = buildExtensionString();
+        pthread_mutex_unlock(&m_lock);
+
+        return m_extensionString;
+    }
+    else {
+        ALOGE("[%s] Unknown name %d\n", __FUNCTION__, name);
+        return NULL;
+    }
+}
+
+/* To get the value of attribute <a> of config <c> use the following formula:
+ * value = *(m_configs + (int)c*m_numConfigAttribs + a);
+ */
+EGLBoolean eglDisplay::getAttribValue(EGLConfig config, EGLint attribIdx, EGLint * value)
+{
+    if (attribIdx == ATTRIBUTE_NONE)
+    {
+        ALOGE("[%s] Bad attribute idx\n", __FUNCTION__);
+        return EGL_FALSE;
+    }
+    *value = *(m_configs + (int)config*m_numConfigAttribs + attribIdx);
+    return EGL_TRUE;
+}
+
+EGLBoolean eglDisplay::getConfigAttrib(EGLConfig config, EGLint attrib, EGLint * value)
+{
+    //Though it seems that valueFor() is thread-safe, we don't take chanses
+    pthread_mutex_lock(&m_lock);
+    EGLBoolean ret = getAttribValue(config, m_attribs.valueFor(attrib), value);
+    pthread_mutex_unlock(&m_lock);
+    return ret;
+}
+
+void eglDisplay::dumpConfig(EGLConfig config)
+{
+    EGLint value = 0;
+    DBG("^^^^^^^^^^ dumpConfig %d ^^^^^^^^^^^^^^^^^^", (int)config);
+    for (int i=0; i<m_numConfigAttribs; i++) {
+        getAttribValue(config, i, &value);
+        DBG("{%d}[%d] %d\n", (int)config, i, value);
+    }
+}
+
+/* To set the value of attribute <a> of config <c> use the following formula:
+ * *(m_configs + (int)c*m_numConfigAttribs + a) = value;
+ */
+EGLBoolean eglDisplay::setAttribValue(EGLConfig config, EGLint attribIdx, EGLint value)
+{
+    if (attribIdx == ATTRIBUTE_NONE)
+    {
+        ALOGE("[%s] Bad attribute idx\n", __FUNCTION__);
+        return EGL_FALSE;
+    }
+    *(m_configs + (int)config*m_numConfigAttribs + attribIdx) = value;
+    return EGL_TRUE;
+}
+
+EGLBoolean eglDisplay::setConfigAttrib(EGLConfig config, EGLint attrib, EGLint value)
+{
+    //Though it seems that valueFor() is thread-safe, we don't take chanses
+    pthread_mutex_lock(&m_lock);
+    EGLBoolean ret = setAttribValue(config, m_attribs.valueFor(attrib), value);
+    pthread_mutex_unlock(&m_lock);
+    return ret;
+}
+
+
+EGLBoolean eglDisplay::getConfigNativePixelFormat(EGLConfig config, PixelFormat * format)
+{
+    EGLint redSize, blueSize, greenSize, alphaSize;
+
+    if ( !(getAttribValue(config, m_attribs.valueFor(EGL_RED_SIZE), &redSize) &&
+        getAttribValue(config, m_attribs.valueFor(EGL_BLUE_SIZE), &blueSize) &&
+        getAttribValue(config, m_attribs.valueFor(EGL_GREEN_SIZE), &greenSize) &&
+        getAttribValue(config, m_attribs.valueFor(EGL_ALPHA_SIZE), &alphaSize)) )
+    {
+        ALOGE("Couldn't find value for one of the pixel format attributes");
+        return EGL_FALSE;
+    }
+
+    //calculate the GL internal format
+    if ((redSize==8)&&(greenSize==8)&&(blueSize==8)&&(alphaSize==8)) *format = PIXEL_FORMAT_RGBA_8888; //XXX: BGR?
+    else if ((redSize==8)&&(greenSize==8)&&(blueSize==8)&&(alphaSize==0)) *format = PIXEL_FORMAT_RGBX_8888; //XXX or PIXEL_FORMAT_RGB_888
+    else if ((redSize==5)&&(greenSize==6)&&(blueSize==5)&&(alphaSize==0)) *format = PIXEL_FORMAT_RGB_565;
+    else if ((redSize==5)&&(greenSize==5)&&(blueSize==5)&&(alphaSize==1)) *format = PIXEL_FORMAT_RGBA_5551;
+    else if ((redSize==4)&&(greenSize==4)&&(blueSize==4)&&(alphaSize==4)) *format = PIXEL_FORMAT_RGBA_4444;
+    else {
+        return EGL_FALSE;
+    }
+    return EGL_TRUE;
+}
+EGLBoolean eglDisplay::getConfigGLPixelFormat(EGLConfig config, GLenum * format)
+{
+    EGLint redSize, blueSize, greenSize, alphaSize;
+
+    if ( !(getAttribValue(config, m_attribs.valueFor(EGL_RED_SIZE), &redSize) &&
+        getAttribValue(config, m_attribs.valueFor(EGL_BLUE_SIZE), &blueSize) &&
+        getAttribValue(config, m_attribs.valueFor(EGL_GREEN_SIZE), &greenSize) &&
+        getAttribValue(config, m_attribs.valueFor(EGL_ALPHA_SIZE), &alphaSize)) )
+    {
+        ALOGE("Couldn't find value for one of the pixel format attributes");
+        return EGL_FALSE;
+    }
+
+    //calculate the GL internal format
+    if ((redSize==8)&&(blueSize==8)&&(blueSize==8)&&(alphaSize==8)) *format = GL_RGBA;
+    else if ((redSize==8)&&(greenSize==8)&&(blueSize==8)&&(alphaSize==0)) *format = GL_RGB;
+    else if ((redSize==5)&&(greenSize==6)&&(blueSize==5)&&(alphaSize==0)) *format = GL_RGB565_OES;
+    else if ((redSize==5)&&(greenSize==5)&&(blueSize==5)&&(alphaSize==1)) *format = GL_RGB5_A1_OES;
+    else if ((redSize==4)&&(greenSize==4)&&(blueSize==4)&&(alphaSize==4)) *format = GL_RGBA4_OES;
+    else return EGL_FALSE;
+
+    return EGL_TRUE;
+}
diff --git a/opengl/system/egl/eglDisplay.h b/opengl/system/egl/eglDisplay.h
new file mode 100644
index 0000000..9d979d9
--- /dev/null
+++ b/opengl/system/egl/eglDisplay.h
@@ -0,0 +1,89 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#ifndef _SYSTEM_EGL_DISPLAY_H
+#define _SYSTEM_EGL_DISPLAY_H
+
+#include <pthread.h>
+#include "glUtils.h"
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include "EGLClientIface.h"
+#include <utils/KeyedVector.h>
+
+#include <ui/PixelFormat.h>
+
+#define ATTRIBUTE_NONE -1
+//FIXME: are we in this namespace?
+using namespace android;
+
+class eglDisplay
+{
+public:
+    eglDisplay();
+    ~eglDisplay();
+
+    bool initialize(EGLClient_eglInterface *eglIface);
+    void terminate();
+
+    int getVersionMajor() const { return m_major; }
+    int getVersionMinor() const { return m_minor; }
+    bool initialized() const { return m_initialized; }
+
+    const char *queryString(EGLint name);
+
+    const EGLClient_glesInterface *gles_iface() const { return m_gles_iface; }
+    const EGLClient_glesInterface *gles2_iface() const { return m_gles2_iface; }
+
+    int     getNumConfigs(){ return m_numConfigs; }
+    EGLBoolean  getConfigAttrib(EGLConfig config, EGLint attrib, EGLint * value);
+    EGLBoolean  setConfigAttrib(EGLConfig config, EGLint attrib, EGLint value);
+    EGLBoolean getConfigGLPixelFormat(EGLConfig config, GLenum * format);
+    EGLBoolean getConfigNativePixelFormat(EGLConfig config, PixelFormat * format);
+
+    void     dumpConfig(EGLConfig config);
+private:
+    EGLClient_glesInterface *loadGLESClientAPI(const char *libName,
+                                               EGLClient_eglInterface *eglIface,
+                                               void **libHandle);
+    EGLBoolean getAttribValue(EGLConfig config, EGLint attribIdxi, EGLint * value);
+    EGLBoolean setAttribValue(EGLConfig config, EGLint attribIdxi, EGLint value);
+    void     processConfigs();
+
+private:
+    pthread_mutex_t m_lock;
+    bool m_initialized;
+    int  m_major;
+    int  m_minor;
+    int  m_hostRendererVersion;
+    int  m_numConfigs;
+    int  m_numConfigAttribs;
+
+    /* This is the mapping between an attribute name to it's index in any given config */
+    DefaultKeyedVector<EGLint, EGLint>    m_attribs;
+    /* This is an array of all config's attributes values stored in the following sequencial fasion (read: v[c,a] = the value of attribute <a> of config <c>)
+     * v[0,0],..,v[0,m_numConfigAttribs-1],
+     *...
+     * v[m_numConfigs-1,0],..,v[m_numConfigs-1,m_numConfigAttribs-1]
+     */
+    EGLint *m_configs;
+    EGLClient_glesInterface *m_gles_iface;
+    EGLClient_glesInterface *m_gles2_iface;
+    char *m_versionString;
+    char *m_vendorString;
+    char *m_extensionString;
+};
+
+#endif
diff --git a/opengl/system/egl/egl_ftable.h b/opengl/system/egl/egl_ftable.h
new file mode 100644
index 0000000..16d130c
--- /dev/null
+++ b/opengl/system/egl/egl_ftable.h
@@ -0,0 +1,64 @@
+/*
+* Copyright (C) 2011 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.
+*/
+static const struct _egl_funcs_by_name {
+    const char *name;
+    void *proc;
+} egl_funcs_by_name[] = {
+    {"eglGetError", (void *)eglGetError},
+    {"eglGetDisplay", (void *)eglGetDisplay},
+    {"eglInitialize", (void *)eglInitialize},
+    {"eglTerminate", (void *)eglTerminate},
+    {"eglQueryString", (void *)eglQueryString},
+    {"eglGetConfigs", (void *)eglGetConfigs},
+    {"eglChooseConfig", (void *)eglChooseConfig},
+    {"eglGetConfigAttrib", (void *)eglGetConfigAttrib},
+    {"eglCreateWindowSurface", (void *)eglCreateWindowSurface},
+    {"eglCreatePbufferSurface", (void *)eglCreatePbufferSurface},
+    {"eglCreatePixmapSurface", (void *)eglCreatePixmapSurface},
+    {"eglDestroySurface", (void *)eglDestroySurface},
+    {"eglQuerySurface", (void *)eglQuerySurface},
+    {"eglBindAPI", (void *)eglBindAPI},
+    {"eglQueryAPI", (void *)eglQueryAPI},
+    {"eglWaitClient", (void *)eglWaitClient},
+    {"eglReleaseThread", (void *)eglReleaseThread},
+    {"eglCreatePbufferFromClientBuffer", (void *)eglCreatePbufferFromClientBuffer},
+    {"eglSurfaceAttrib", (void *)eglSurfaceAttrib},
+    {"eglBindTexImage", (void *)eglBindTexImage},
+    {"eglReleaseTexImage", (void *)eglReleaseTexImage},
+    {"eglSwapInterval", (void *)eglSwapInterval},
+    {"eglCreateContext", (void *)eglCreateContext},
+    {"eglDestroyContext", (void *)eglDestroyContext},
+    {"eglMakeCurrent", (void *)eglMakeCurrent},
+    {"eglGetCurrentContext", (void *)eglGetCurrentContext},
+    {"eglGetCurrentSurface", (void *)eglGetCurrentSurface},
+    {"eglGetCurrentDisplay", (void *)eglGetCurrentDisplay},
+    {"eglQueryContext", (void *)eglQueryContext},
+    {"eglWaitGL", (void *)eglWaitGL},
+    {"eglWaitNative", (void *)eglWaitNative},
+    {"eglSwapBuffers", (void *)eglSwapBuffers},
+    {"eglCopyBuffers", (void *)eglCopyBuffers},
+    {"eglGetProcAddress", (void *)eglGetProcAddress},
+    {"eglLockSurfaceKHR", (void *)eglLockSurfaceKHR},
+    {"eglUnlockSurfaceKHR", (void *)eglUnlockSurfaceKHR},
+    {"eglCreateImageKHR", (void *)eglCreateImageKHR},
+    {"eglDestroyImageKHR", (void *)eglDestroyImageKHR},
+    {"eglCreateSyncKHR", (void *)eglCreateSyncKHR},
+    {"eglDestroySyncKHR", (void *)eglDestroySyncKHR},
+    {"eglClientWaitSyncKHR", (void *)eglClientWaitSyncKHR},
+    {"eglGetSyncAttribKHR", (void *)eglGetSyncAttribKHR}
+};
+
+static const int egl_num_funcs = sizeof(egl_funcs_by_name) / sizeof(struct _egl_funcs_by_name);
diff --git a/opengl/system/gralloc/Android.mk b/opengl/system/gralloc/Android.mk
new file mode 100644
index 0000000..8705602
--- /dev/null
+++ b/opengl/system/gralloc/Android.mk
@@ -0,0 +1,19 @@
+ifneq (false,$(BUILD_EMULATOR_OPENGL_DRIVER))
+
+LOCAL_PATH := $(call my-dir)
+
+$(call emugl-begin-shared-library,gralloc.goldfish)
+$(call emugl-import,libGLESv1_enc lib_renderControl_enc libOpenglSystemCommon)
+$(call emugl-set-shared-library-subpath,hw)
+
+LOCAL_CFLAGS += -DLOG_TAG=\"gralloc_goldfish\"
+
+LOCAL_SRC_FILES := gralloc.cpp
+
+# Need to access the special OPENGL TLS Slot
+LOCAL_C_INCLUDES += bionic/libc/private
+LOCAL_SHARED_LIBRARIES += libdl
+
+$(call emugl-end-module)
+
+endif # BUILD_EMULATOR_OPENGL_DRIVER != false
diff --git a/opengl/system/gralloc/gralloc.cpp b/opengl/system/gralloc/gralloc.cpp
new file mode 100644
index 0000000..ac20d49
--- /dev/null
+++ b/opengl/system/gralloc/gralloc.cpp
@@ -0,0 +1,929 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#include <string.h>
+#include <pthread.h>
+#ifdef HAVE_ANDROID_OS      // just want PAGE_SIZE define
+# include <asm/page.h>
+#else
+# include <sys/user.h>
+#endif
+#include <cutils/ashmem.h>
+#include <unistd.h>
+#include <errno.h>
+#include <dlfcn.h>
+#include <sys/mman.h>
+#include "gralloc_cb.h"
+#include "HostConnection.h"
+#include "glUtils.h"
+#include <cutils/log.h>
+#include <cutils/properties.h>
+
+/* Set to 1 or 2 to enable debug traces */
+#define DEBUG  0
+
+#if DEBUG >= 1
+#  define D(...)   ALOGD(__VA_ARGS__)
+#else
+#  define D(...)   ((void)0)
+#endif
+
+#if DEBUG >= 2
+#  define DD(...)  ALOGD(__VA_ARGS__)
+#else
+#  define DD(...)  ((void)0)
+#endif
+
+#define DBG_FUNC DBG("%s\n", __FUNCTION__)
+//
+// our private gralloc module structure
+//
+struct private_module_t {
+    gralloc_module_t base;
+};
+
+/* If not NULL, this is a pointer to the fallback module.
+ * This really is gralloc.default, which we'll use if we detect
+ * that the emulator we're running in does not support GPU emulation.
+ */
+static gralloc_module_t*  sFallback;
+static pthread_once_t     sFallbackOnce = PTHREAD_ONCE_INIT;
+
+static void fallback_init(void);  // forward
+
+
+typedef struct _alloc_list_node {
+    buffer_handle_t handle;
+    _alloc_list_node *next;
+    _alloc_list_node *prev;
+} AllocListNode;
+
+//
+// Our gralloc device structure (alloc interface)
+//
+struct gralloc_device_t {
+    alloc_device_t  device;
+
+    AllocListNode *allocListHead;    // double linked list of allocated buffers
+    pthread_mutex_t lock;
+};
+
+//
+// Our framebuffer device structure
+//
+struct fb_device_t {
+    framebuffer_device_t  device;
+};
+
+static int map_buffer(cb_handle_t *cb, void **vaddr)
+{
+    if (cb->fd < 0 || cb->ashmemSize <= 0) {
+        return -EINVAL;
+    }
+
+    void *addr = mmap(0, cb->ashmemSize, PROT_READ | PROT_WRITE,
+                      MAP_SHARED, cb->fd, 0);
+    if (addr == MAP_FAILED) {
+        return -errno;
+    }
+
+    cb->ashmemBase = intptr_t(addr);
+    cb->ashmemBasePid = getpid();
+
+    *vaddr = addr;
+    return 0;
+}
+
+#define DEFINE_HOST_CONNECTION \
+    HostConnection *hostCon = HostConnection::get(); \
+    renderControl_encoder_context_t *rcEnc = (hostCon ? hostCon->rcEncoder() : NULL)
+
+#define DEFINE_AND_VALIDATE_HOST_CONNECTION \
+    HostConnection *hostCon = HostConnection::get(); \
+    if (!hostCon) { \
+        ALOGE("gralloc: Failed to get host connection\n"); \
+        return -EIO; \
+    } \
+    renderControl_encoder_context_t *rcEnc = hostCon->rcEncoder(); \
+    if (!rcEnc) { \
+        ALOGE("gralloc: Failed to get renderControl encoder context\n"); \
+        return -EIO; \
+    }
+
+
+//
+// gralloc device functions (alloc interface)
+//
+static int gralloc_alloc(alloc_device_t* dev,
+                         int w, int h, int format, int usage,
+                         buffer_handle_t* pHandle, int* pStride)
+{
+    D("gralloc_alloc w=%d h=%d usage=0x%x\n", w, h, usage);
+
+    gralloc_device_t *grdev = (gralloc_device_t *)dev;
+    if (!grdev || !pHandle || !pStride) {
+        ALOGE("gralloc_alloc: Bad inputs (grdev: %p, pHandle: %p, pStride: %p",
+                grdev, pHandle, pStride);
+        return -EINVAL;
+    }
+
+    //
+    // Validate usage: buffer cannot be written both by s/w and h/w access.
+    //
+    bool sw_write = (0 != (usage & GRALLOC_USAGE_SW_WRITE_MASK));
+    bool hw_write = (usage & GRALLOC_USAGE_HW_RENDER);
+    if (hw_write && sw_write) {
+        ALOGE("gralloc_alloc: Mismatched usage flags: %d x %d, usage %x",
+                w, h, usage);
+        return -EINVAL;
+    }
+    bool sw_read = (0 != (usage & GRALLOC_USAGE_SW_READ_MASK));
+    bool hw_cam_write = usage & GRALLOC_USAGE_HW_CAMERA_WRITE;
+    bool hw_cam_read = usage & GRALLOC_USAGE_HW_CAMERA_READ;
+    bool hw_vid_enc_read = usage & GRALLOC_USAGE_HW_VIDEO_ENCODER;
+
+    // Pick the right concrete pixel format given the endpoints as encoded in
+    // the usage bits.  Every end-point pair needs explicit listing here.
+    if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
+        // Camera as producer
+        if (usage & GRALLOC_USAGE_HW_CAMERA_WRITE) {
+            if (usage & GRALLOC_USAGE_HW_TEXTURE) {
+                // Camera-to-display is RGBA
+                format = HAL_PIXEL_FORMAT_RGBA_8888;
+            } else if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) {
+                // Camera-to-encoder is NV21
+                format = HAL_PIXEL_FORMAT_YCrCb_420_SP;
+            } else if ((usage & GRALLOC_USAGE_HW_CAMERA_MASK) ==
+                    GRALLOC_USAGE_HW_CAMERA_ZSL) {
+                // Camera-to-ZSL-queue is RGB_888
+                format = HAL_PIXEL_FORMAT_RGB_888;
+            }
+        }
+
+        if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
+            ALOGE("gralloc_alloc: Requested auto format selection, "
+                    "but no known format for this usage: %d x %d, usage %x",
+                    w, h, usage);
+            return -EINVAL;
+        }
+    }
+
+    bool yuv_format = false;
+
+    int ashmem_size = 0;
+    int stride = w;
+
+    GLenum glFormat = 0;
+    GLenum glType = 0;
+
+    int bpp = 0;
+    int align = 1;
+    switch (format) {
+        case HAL_PIXEL_FORMAT_RGBA_8888:
+        case HAL_PIXEL_FORMAT_RGBX_8888:
+        case HAL_PIXEL_FORMAT_BGRA_8888:
+            bpp = 4;
+            glFormat = GL_RGBA;
+            glType = GL_UNSIGNED_BYTE;
+            break;
+        case HAL_PIXEL_FORMAT_RGB_888:
+            bpp = 3;
+            glFormat = GL_RGB;
+            glType = GL_UNSIGNED_BYTE;
+            break;
+        case HAL_PIXEL_FORMAT_RGB_565:
+            bpp = 2;
+            glFormat = GL_RGB;
+            glType = GL_UNSIGNED_SHORT_5_6_5;
+            break;
+        case HAL_PIXEL_FORMAT_RGBA_5551:
+            bpp = 2;
+            glFormat = GL_RGB5_A1_OES;
+            glType = GL_UNSIGNED_SHORT_5_5_5_1;
+            break;
+        case HAL_PIXEL_FORMAT_RGBA_4444:
+            bpp = 2;
+            glFormat = GL_RGBA4_OES;
+            glType = GL_UNSIGNED_SHORT_4_4_4_4;
+            break;
+        case HAL_PIXEL_FORMAT_RAW_SENSOR:
+            bpp = 2;
+            align = 16*bpp;
+            if (! ((sw_read || hw_cam_read) && (sw_write || hw_cam_write) ) ) {
+                // Raw sensor data only goes between camera and CPU
+                return -EINVAL;
+            }
+            // Not expecting to actually create any GL surfaces for this
+            glFormat = GL_LUMINANCE;
+            glType = GL_UNSIGNED_SHORT;
+            break;
+        case HAL_PIXEL_FORMAT_BLOB:
+            bpp = 1;
+            if (! (sw_read && hw_cam_write) ) {
+                // Blob data cannot be used by HW other than camera emulator
+                return -EINVAL;
+            }
+            // Not expecting to actually create any GL surfaces for this
+            glFormat = GL_LUMINANCE;
+            glType = GL_UNSIGNED_BYTE;
+            break;
+        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+            align = 1;
+            bpp = 1; // per-channel bpp
+            yuv_format = true;
+            // Not expecting to actually create any GL surfaces for this
+            break;
+        case HAL_PIXEL_FORMAT_YV12:
+            align = 16;
+            bpp = 1; // per-channel bpp
+            yuv_format = true;
+            // Not expecting to actually create any GL surfaces for this
+            break;
+        default:
+            ALOGE("gralloc_alloc: Unknown format %d", format);
+            return -EINVAL;
+    }
+
+    if (usage & GRALLOC_USAGE_HW_FB) {
+        // keep space for postCounter
+        ashmem_size += sizeof(uint32_t);
+    }
+
+    if (sw_read || sw_write || hw_cam_write || hw_vid_enc_read) {
+        // keep space for image on guest memory if SW access is needed
+        // or if the camera is doing writing
+        if (yuv_format) {
+            size_t yStride = (w*bpp + (align - 1)) & ~(align-1);
+            size_t uvStride = (yStride / 2 + (align - 1)) & ~(align-1);
+            size_t uvHeight = h / 2;
+            ashmem_size += yStride * h + 2 * (uvHeight * uvStride);
+            stride = yStride / bpp;
+        } else {
+            size_t bpr = (w*bpp + (align-1)) & ~(align-1);
+            ashmem_size += (bpr * h);
+            stride = bpr / bpp;
+        }
+    }
+
+    D("gralloc_alloc format=%d, ashmem_size=%d, stride=%d, tid %d\n", format,
+            ashmem_size, stride, gettid());
+
+    //
+    // Allocate space in ashmem if needed
+    //
+    int fd = -1;
+    if (ashmem_size > 0) {
+        // round to page size;
+        ashmem_size = (ashmem_size + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1);
+
+        fd = ashmem_create_region("gralloc-buffer", ashmem_size);
+        if (fd < 0) {
+            ALOGE("gralloc_alloc failed to create ashmem region: %s\n",
+                    strerror(errno));
+            return -errno;
+        }
+    }
+
+    cb_handle_t *cb = new cb_handle_t(fd, ashmem_size, usage,
+                                      w, h, format, glFormat, glType);
+
+    if (ashmem_size > 0) {
+        //
+        // map ashmem region if exist
+        //
+        void *vaddr;
+        int err = map_buffer(cb, &vaddr);
+        if (err) {
+            close(fd);
+            delete cb;
+            return err;
+        }
+
+        cb->setFd(fd);
+    }
+
+    //
+    // Allocate ColorBuffer handle on the host (only if h/w access is allowed)
+    // Only do this for some h/w usages, not all.
+    //
+    if (usage & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_RENDER |
+                    GRALLOC_USAGE_HW_2D | GRALLOC_USAGE_HW_COMPOSER |
+                    GRALLOC_USAGE_HW_FB) ) {
+        DEFINE_HOST_CONNECTION;
+        if (hostCon && rcEnc) {
+            cb->hostHandle = rcEnc->rcCreateColorBuffer(rcEnc, w, h, glFormat);
+            D("Created host ColorBuffer 0x%x\n", cb->hostHandle);
+        }
+
+        if (!cb->hostHandle) {
+           // Could not create colorbuffer on host !!!
+           close(fd);
+           delete cb;
+           return -EIO;
+        }
+    }
+
+    //
+    // alloc succeeded - insert the allocated handle to the allocated list
+    //
+    AllocListNode *node = new AllocListNode();
+    pthread_mutex_lock(&grdev->lock);
+    node->handle = cb;
+    node->next =  grdev->allocListHead;
+    node->prev =  NULL;
+    if (grdev->allocListHead) {
+        grdev->allocListHead->prev = node;
+    }
+    grdev->allocListHead = node;
+    pthread_mutex_unlock(&grdev->lock);
+
+    *pHandle = cb;
+    *pStride = stride;
+    return 0;
+}
+
+static int gralloc_free(alloc_device_t* dev,
+                        buffer_handle_t handle)
+{
+    const cb_handle_t *cb = (const cb_handle_t *)handle;
+    if (!cb_handle_t::validate((cb_handle_t*)cb)) {
+        ERR("gralloc_free: invalid handle");
+        return -EINVAL;
+    }
+
+    if (cb->hostHandle != 0) {
+        DEFINE_AND_VALIDATE_HOST_CONNECTION;
+        D("Closing host ColorBuffer 0x%x\n", cb->hostHandle);
+        rcEnc->rcCloseColorBuffer(rcEnc, cb->hostHandle);
+    }
+
+    //
+    // detach and unmap ashmem area if present
+    //
+    if (cb->fd > 0) {
+        if (cb->ashmemSize > 0 && cb->ashmemBase) {
+            munmap((void *)cb->ashmemBase, cb->ashmemSize);
+        }
+        close(cb->fd);
+    }
+
+    // remove it from the allocated list
+    gralloc_device_t *grdev = (gralloc_device_t *)dev;
+    pthread_mutex_lock(&grdev->lock);
+    AllocListNode *n = grdev->allocListHead;
+    while( n && n->handle != cb ) {
+        n = n->next;
+    }
+    if (n) {
+       // buffer found on list - remove it from list
+       if (n->next) {
+           n->next->prev = n->prev;
+       }
+       if (n->prev) {
+           n->prev->next = n->next;
+       }
+       else {
+           grdev->allocListHead = n->next;
+       }
+
+       delete n;
+    }
+    pthread_mutex_unlock(&grdev->lock);
+
+    delete cb;
+
+    return 0;
+}
+
+static int gralloc_device_close(struct hw_device_t *dev)
+{
+    gralloc_device_t* d = reinterpret_cast<gralloc_device_t*>(dev);
+    if (d) {
+
+        // free still allocated buffers
+        while( d->allocListHead != NULL ) {
+            gralloc_free(&d->device, d->allocListHead->handle);
+        }
+
+        // free device
+        free(d);
+    }
+    return 0;
+}
+
+static int fb_compositionComplete(struct framebuffer_device_t* dev)
+{
+    return 0;
+}
+
+//
+// Framebuffer device functions
+//
+static int fb_post(struct framebuffer_device_t* dev, buffer_handle_t buffer)
+{
+    fb_device_t *fbdev = (fb_device_t *)dev;
+    cb_handle_t *cb = (cb_handle_t *)buffer;
+
+    if (!fbdev || !cb_handle_t::validate(cb) || !cb->canBePosted()) {
+        return -EINVAL;
+    }
+
+    // Make sure we have host connection
+    DEFINE_AND_VALIDATE_HOST_CONNECTION;
+
+    // increment the post count of the buffer
+    uint32_t *postCountPtr = (uint32_t *)cb->ashmemBase;
+    if (!postCountPtr) {
+        // This should not happen
+        return -EINVAL;
+    }
+    (*postCountPtr)++;
+
+    // send post request to host
+    rcEnc->rcFBPost(rcEnc, cb->hostHandle);
+    hostCon->flush();
+
+    return 0;
+}
+
+static int fb_setUpdateRect(struct framebuffer_device_t* dev,
+        int l, int t, int w, int h)
+{
+    fb_device_t *fbdev = (fb_device_t *)dev;
+
+    if (!fbdev) {
+        return -EINVAL;
+    }
+
+    // Make sure we have host connection
+    DEFINE_AND_VALIDATE_HOST_CONNECTION;
+
+    // send request to host
+    // TODO: XXX - should be implemented
+    //rcEnc->rc_XXX
+
+    return 0;
+}
+
+static int fb_setSwapInterval(struct framebuffer_device_t* dev,
+            int interval)
+{
+    fb_device_t *fbdev = (fb_device_t *)dev;
+
+    if (!fbdev) {
+        return -EINVAL;
+    }
+
+    // Make sure we have host connection
+    DEFINE_AND_VALIDATE_HOST_CONNECTION;
+
+    // send request to host
+    rcEnc->rcFBSetSwapInterval(rcEnc, interval);
+    hostCon->flush();
+
+    return 0;
+}
+
+static int fb_close(struct hw_device_t *dev)
+{
+    fb_device_t *fbdev = (fb_device_t *)dev;
+
+    delete fbdev;
+
+    return 0;
+}
+
+
+//
+// gralloc module functions - refcount + locking interface
+//
+static int gralloc_register_buffer(gralloc_module_t const* module,
+                                   buffer_handle_t handle)
+{
+    pthread_once(&sFallbackOnce, fallback_init);
+    if (sFallback != NULL) {
+        return sFallback->registerBuffer(sFallback, handle);
+    }
+
+    D("gralloc_register_buffer(%p) called", handle);
+
+    private_module_t *gr = (private_module_t *)module;
+    cb_handle_t *cb = (cb_handle_t *)handle;
+    if (!gr || !cb_handle_t::validate(cb)) {
+        ERR("gralloc_register_buffer(%p): invalid buffer", cb);
+        return -EINVAL;
+    }
+
+    if (cb->hostHandle != 0) {
+        DEFINE_AND_VALIDATE_HOST_CONNECTION;
+        D("Opening host ColorBuffer 0x%x\n", cb->hostHandle);
+        rcEnc->rcOpenColorBuffer(rcEnc, cb->hostHandle);
+    }
+
+    //
+    // if the color buffer has ashmem region and it is not mapped in this
+    // process map it now.
+    //
+    if (cb->ashmemSize > 0 && cb->mappedPid != getpid()) {
+        void *vaddr;
+        int err = map_buffer(cb, &vaddr);
+        if (err) {
+            ERR("gralloc_register_buffer(%p): map failed: %s", cb, strerror(-err));
+            return -err;
+        }
+        cb->mappedPid = getpid();
+    }
+
+    return 0;
+}
+
+static int gralloc_unregister_buffer(gralloc_module_t const* module,
+                                     buffer_handle_t handle)
+{
+    if (sFallback != NULL) {
+        return sFallback->unregisterBuffer(sFallback, handle);
+    }
+
+    private_module_t *gr = (private_module_t *)module;
+    cb_handle_t *cb = (cb_handle_t *)handle;
+    if (!gr || !cb_handle_t::validate(cb)) {
+        ERR("gralloc_unregister_buffer(%p): invalid buffer", cb);
+        return -EINVAL;
+    }
+
+    if (cb->hostHandle != 0) {
+        DEFINE_AND_VALIDATE_HOST_CONNECTION;
+        D("Closing host ColorBuffer 0x%x\n", cb->hostHandle);
+        rcEnc->rcCloseColorBuffer(rcEnc, cb->hostHandle);
+    }
+
+    //
+    // unmap ashmem region if it was previously mapped in this process
+    // (through register_buffer)
+    //
+    if (cb->ashmemSize > 0 && cb->mappedPid == getpid()) {
+        void *vaddr;
+        int err = munmap((void *)cb->ashmemBase, cb->ashmemSize);
+        if (err) {
+            ERR("gralloc_unregister_buffer(%p): unmap failed", cb);
+            return -EINVAL;
+        }
+        cb->ashmemBase = NULL;
+        cb->mappedPid = 0;
+    }
+
+    D("gralloc_unregister_buffer(%p) done\n", cb);
+
+    return 0;
+}
+
+static int gralloc_lock(gralloc_module_t const* module,
+                        buffer_handle_t handle, int usage,
+                        int l, int t, int w, int h,
+                        void** vaddr)
+{
+    if (sFallback != NULL) {
+        return sFallback->lock(sFallback, handle, usage, l, t, w, h, vaddr);
+    }
+
+    private_module_t *gr = (private_module_t *)module;
+    cb_handle_t *cb = (cb_handle_t *)handle;
+    if (!gr || !cb_handle_t::validate(cb)) {
+        ALOGE("gralloc_lock bad handle\n");
+        return -EINVAL;
+    }
+
+    // Validate usage,
+    //   1. cannot be locked for hw access
+    //   2. lock for either sw read or write.
+    //   3. locked sw access must match usage during alloc time.
+    bool sw_read = (0 != (usage & GRALLOC_USAGE_SW_READ_MASK));
+    bool sw_write = (0 != (usage & GRALLOC_USAGE_SW_WRITE_MASK));
+    bool hw_read = (usage & GRALLOC_USAGE_HW_TEXTURE);
+    bool hw_write = (usage & GRALLOC_USAGE_HW_RENDER);
+    bool hw_vid_enc_read = (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER);
+    bool hw_cam_write = (usage & GRALLOC_USAGE_HW_CAMERA_WRITE);
+    bool hw_cam_read = (usage & GRALLOC_USAGE_HW_CAMERA_READ);
+    bool sw_read_allowed = (0 != (cb->usage & GRALLOC_USAGE_SW_READ_MASK));
+    bool sw_write_allowed = (0 != (cb->usage & GRALLOC_USAGE_SW_WRITE_MASK));
+
+    if ( (hw_read || hw_write) ||
+         (!sw_read && !sw_write &&
+                 !hw_cam_write && !hw_cam_read &&
+                 !hw_vid_enc_read) ||
+         (sw_read && !sw_read_allowed) ||
+         (sw_write && !sw_write_allowed) ) {
+        ALOGE("gralloc_lock usage mismatch usage=0x%x cb->usage=0x%x\n", usage,
+                cb->usage);
+        return -EINVAL;
+    }
+
+    EGLint postCount = 0;
+    void *cpu_addr = NULL;
+
+    //
+    // make sure ashmem area is mapped if needed
+    //
+    if (cb->canBePosted() || sw_read || sw_write ||
+            hw_cam_write || hw_cam_read ||
+            hw_vid_enc_read) {
+        if (cb->ashmemBasePid != getpid() || !cb->ashmemBase) {
+            return -EACCES;
+        }
+
+        if (cb->canBePosted()) {
+            postCount = *((int *)cb->ashmemBase);
+            cpu_addr = (void *)(cb->ashmemBase + sizeof(int));
+        }
+        else {
+            cpu_addr = (void *)(cb->ashmemBase);
+        }
+    }
+
+    if (cb->hostHandle) {
+        // Make sure we have host connection
+        DEFINE_AND_VALIDATE_HOST_CONNECTION;
+
+        //
+        // flush color buffer write cache on host and get its sync status.
+        //
+        int hostSyncStatus = rcEnc->rcColorBufferCacheFlush(rcEnc, cb->hostHandle,
+                                                            postCount,
+                                                            sw_read);
+        if (hostSyncStatus < 0) {
+            // host failed the color buffer sync - probably since it was already
+            // locked for write access. fail the lock.
+            ALOGE("gralloc_lock cacheFlush failed postCount=%d sw_read=%d\n",
+                 postCount, sw_read);
+            return -EBUSY;
+        }
+
+    }
+
+    //
+    // is virtual address required ?
+    //
+    if (sw_read || sw_write || hw_cam_write || hw_cam_read || hw_vid_enc_read) {
+        *vaddr = cpu_addr;
+    }
+
+    if (sw_write || hw_cam_write) {
+        //
+        // Keep locked region if locked for s/w write access.
+        //
+        cb->lockedLeft = l;
+        cb->lockedTop = t;
+        cb->lockedWidth = w;
+        cb->lockedHeight = h;
+    }
+
+    DD("gralloc_lock success. vaddr: %p, *vaddr: %p, usage: %x, cpu_addr: %p",
+            vaddr, vaddr ? *vaddr : 0, usage, cpu_addr);
+
+    return 0;
+}
+
+static int gralloc_unlock(gralloc_module_t const* module,
+                          buffer_handle_t handle)
+{
+    if (sFallback != NULL) {
+        return sFallback->unlock(sFallback, handle);
+    }
+
+    private_module_t *gr = (private_module_t *)module;
+    cb_handle_t *cb = (cb_handle_t *)handle;
+    if (!gr || !cb_handle_t::validate(cb)) {
+        return -EINVAL;
+    }
+
+    //
+    // if buffer was locked for s/w write, we need to update the host with
+    // the updated data
+    //
+    if (cb->lockedWidth > 0 && cb->lockedHeight > 0 && cb->hostHandle) {
+
+        // Make sure we have host connection
+        DEFINE_AND_VALIDATE_HOST_CONNECTION;
+
+        void *cpu_addr;
+        if (cb->canBePosted()) {
+            cpu_addr = (void *)(cb->ashmemBase + sizeof(int));
+        }
+        else {
+            cpu_addr = (void *)(cb->ashmemBase);
+        }
+
+        if (cb->lockedWidth < cb->width || cb->lockedHeight < cb->height) {
+            int bpp = glUtilsPixelBitSize(cb->glFormat, cb->glType) >> 3;
+            char *tmpBuf = new char[cb->lockedWidth * cb->lockedHeight * bpp];
+
+            int dst_line_len = cb->lockedWidth * bpp;
+            int src_line_len = cb->width * bpp;
+            char *src = (char *)cpu_addr + cb->lockedTop*src_line_len + cb->lockedLeft*bpp;
+            char *dst = tmpBuf;
+            for (int y=0; y<cb->lockedHeight; y++) {
+                memcpy(dst, src, dst_line_len);
+                src += src_line_len;
+                dst += dst_line_len;
+            }
+
+            rcEnc->rcUpdateColorBuffer(rcEnc, cb->hostHandle,
+                                       cb->lockedLeft, cb->lockedTop,
+                                       cb->lockedWidth, cb->lockedHeight,
+                                       cb->glFormat, cb->glType,
+                                       tmpBuf);
+
+            delete [] tmpBuf;
+        }
+        else {
+            rcEnc->rcUpdateColorBuffer(rcEnc, cb->hostHandle, 0, 0,
+                                       cb->width, cb->height,
+                                       cb->glFormat, cb->glType,
+                                       cpu_addr);
+        }
+    }
+
+    cb->lockedWidth = cb->lockedHeight = 0;
+    return 0;
+}
+
+
+static int gralloc_device_open(const hw_module_t* module,
+                               const char* name,
+                               hw_device_t** device)
+{
+    int status = -EINVAL;
+
+    D("gralloc_device_open %s\n", name);
+
+    pthread_once( &sFallbackOnce, fallback_init );
+    if (sFallback != NULL) {
+        return sFallback->common.methods->open(&sFallback->common, name, device);
+    }
+
+    if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) {
+
+        // Create host connection and keep it in the TLS.
+        // return error if connection with host can not be established
+        HostConnection *hostCon = HostConnection::get();
+        if (!hostCon) {
+            ALOGE("gralloc: failed to get host connection while opening %s\n", name);
+            return -EIO;
+        }
+
+        //
+        // Allocate memory for the gralloc device (alloc interface)
+        //
+        gralloc_device_t *dev;
+        dev = (gralloc_device_t*)malloc(sizeof(gralloc_device_t));
+        if (NULL == dev) {
+            return -ENOMEM;
+        }
+
+        // Initialize our device structure
+        //
+        dev->device.common.tag = HARDWARE_DEVICE_TAG;
+        dev->device.common.version = 0;
+        dev->device.common.module = const_cast<hw_module_t*>(module);
+        dev->device.common.close = gralloc_device_close;
+
+        dev->device.alloc   = gralloc_alloc;
+        dev->device.free    = gralloc_free;
+        dev->allocListHead  = NULL;
+        pthread_mutex_init(&dev->lock, NULL);
+
+        *device = &dev->device.common;
+        status = 0;
+    }
+    else if (!strcmp(name, GRALLOC_HARDWARE_FB0)) {
+
+        // return error if connection with host can not be established
+        DEFINE_AND_VALIDATE_HOST_CONNECTION;
+
+        //
+        // Query the host for Framebuffer attributes
+        //
+        D("gralloc: query Frabuffer attribs\n");
+        EGLint width = rcEnc->rcGetFBParam(rcEnc, FB_WIDTH);
+        D("gralloc: width=%d\n", width);
+        EGLint height = rcEnc->rcGetFBParam(rcEnc, FB_HEIGHT);
+        D("gralloc: height=%d\n", height);
+        EGLint xdpi = rcEnc->rcGetFBParam(rcEnc, FB_XDPI);
+        D("gralloc: xdpi=%d\n", xdpi);
+        EGLint ydpi = rcEnc->rcGetFBParam(rcEnc, FB_YDPI);
+        D("gralloc: ydpi=%d\n", ydpi);
+        EGLint fps = rcEnc->rcGetFBParam(rcEnc, FB_FPS);
+        D("gralloc: fps=%d\n", fps);
+        EGLint min_si = rcEnc->rcGetFBParam(rcEnc, FB_MIN_SWAP_INTERVAL);
+        D("gralloc: min_swap=%d\n", min_si);
+        EGLint max_si = rcEnc->rcGetFBParam(rcEnc, FB_MAX_SWAP_INTERVAL);
+        D("gralloc: max_swap=%d\n", max_si);
+
+        //
+        // Allocate memory for the framebuffer device
+        //
+        fb_device_t *dev;
+        dev = (fb_device_t*)malloc(sizeof(fb_device_t));
+        if (NULL == dev) {
+            return -ENOMEM;
+        }
+        memset(dev, 0, sizeof(fb_device_t));
+
+        // Initialize our device structure
+        //
+        dev->device.common.tag = HARDWARE_DEVICE_TAG;
+        dev->device.common.version = 0;
+        dev->device.common.module = const_cast<hw_module_t*>(module);
+        dev->device.common.close = fb_close;
+        dev->device.setSwapInterval = fb_setSwapInterval;
+        dev->device.post            = fb_post;
+        dev->device.setUpdateRect   = 0; //fb_setUpdateRect;
+        dev->device.compositionComplete = fb_compositionComplete; //XXX: this is a dummy
+
+        const_cast<uint32_t&>(dev->device.flags) = 0;
+        const_cast<uint32_t&>(dev->device.width) = width;
+        const_cast<uint32_t&>(dev->device.height) = height;
+        const_cast<int&>(dev->device.stride) = width;
+        const_cast<int&>(dev->device.format) = HAL_PIXEL_FORMAT_RGBA_8888;
+        const_cast<float&>(dev->device.xdpi) = xdpi;
+        const_cast<float&>(dev->device.ydpi) = ydpi;
+        const_cast<float&>(dev->device.fps) = fps;
+        const_cast<int&>(dev->device.minSwapInterval) = min_si;
+        const_cast<int&>(dev->device.maxSwapInterval) = max_si;
+        *device = &dev->device.common;
+
+        status = 0;
+    }
+
+    return status;
+}
+
+//
+// define the HMI symbol - our module interface
+//
+static struct hw_module_methods_t gralloc_module_methods = {
+        open: gralloc_device_open
+};
+
+struct private_module_t HAL_MODULE_INFO_SYM = {
+    base: {
+        common: {
+            tag: HARDWARE_MODULE_TAG,
+            version_major: 1,
+            version_minor: 0,
+            id: GRALLOC_HARDWARE_MODULE_ID,
+            name: "Graphics Memory Allocator Module",
+            author: "The Android Open Source Project",
+            methods: &gralloc_module_methods,
+            dso: NULL,
+            reserved: {0, }
+        },
+        registerBuffer: gralloc_register_buffer,
+        unregisterBuffer: gralloc_unregister_buffer,
+        lock: gralloc_lock,
+        unlock: gralloc_unlock,
+        perform: NULL,
+        reserved_proc : {NULL, }
+    }
+};
+
+/* This function is called once to detect whether the emulator supports
+ * GPU emulation (this is done by looking at the qemu.gles kernel
+ * parameter, which must be > 0 if this is the case).
+ *
+ * If not, then load gralloc.default instead as a fallback.
+ */
+static void
+fallback_init(void)
+{
+    char  prop[PROPERTY_VALUE_MAX];
+    void* module;
+
+    property_get("ro.kernel.qemu.gles", prop, "0");
+    if (atoi(prop) > 0) {
+        return;
+    }
+    ALOGD("Emulator without GPU emulation detected.");
+    module = dlopen("/system/lib/hw/gralloc.default.so", RTLD_LAZY|RTLD_LOCAL);
+    if (module != NULL) {
+        sFallback = reinterpret_cast<gralloc_module_t*>(dlsym(module, HAL_MODULE_INFO_SYM_AS_STR));
+        if (sFallback == NULL) {
+            dlclose(module);
+        }
+    }
+    if (sFallback == NULL) {
+        ALOGE("Could not find software fallback module!?");
+    }
+}
diff --git a/opengl/system/renderControl_enc/Android.mk b/opengl/system/renderControl_enc/Android.mk
new file mode 100644
index 0000000..5792440
--- /dev/null
+++ b/opengl/system/renderControl_enc/Android.mk
@@ -0,0 +1,12 @@
+LOCAL_PATH := $(call my-dir)
+
+$(call emugl-begin-shared-library,lib_renderControl_enc)
+
+LOCAL_SRC_FILES := \
+    renderControl_client_context.cpp \
+    renderControl_enc.cpp \
+    renderControl_entry.cpp
+
+$(call emugl-export,C_INCLUDES,$(LOCAL_PATH))
+$(call emugl-import,libOpenglCodecCommon)
+$(call emugl-end-module)
diff --git a/opengl/system/renderControl_enc/README b/opengl/system/renderControl_enc/README
new file mode 100644
index 0000000..2ee1a57
--- /dev/null
+++ b/opengl/system/renderControl_enc/README
@@ -0,0 +1,136 @@
+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, with an initial
+       reference count of 1.
+
+void rcOpenColorBuffer(uint32_t colorbuffer);
+       Adds an additional reference to the colorbuffer, typically from a
+       different Android process than the one which created it.
+
+void rcCloseColorBuffer(uint32_t colorbuffer);
+       Removes a reference to the colorbuffer. When the reference count drops
+       to zero the colorbuffer is automatically destroyed.
+
+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.
diff --git a/opengl/system/renderControl_enc/renderControl.attrib b/opengl/system/renderControl_enc/renderControl.attrib
new file mode 100644
index 0000000..8b9972f
--- /dev/null
+++ b/opengl/system/renderControl_enc/renderControl.attrib
@@ -0,0 +1,41 @@
+GLOBAL
+	base_opcode 10000
+	encoder_headers <stdint.h> <EGL/egl.h> "glUtils.h"
+
+rcGetEGLVersion
+    dir major out
+    len major sizeof(EGLint)
+    dir minor out
+    len minor sizeof(EGLint)
+
+rcQueryEGLString
+    dir buffer out
+    len buffer bufferSize
+
+rcGetGLString
+    dir buffer out
+    len buffer bufferSize
+
+rcGetNumConfigs
+    dir numAttribs out
+    len numAttribs sizeof(uint32_t)
+
+rcGetConfigs
+    dir buffer out
+    len buffer bufSize
+
+rcChooseConfig
+    dir attribs in
+    len attribs attribs_size
+    dir configs out
+    var_flag configs nullAllowed
+    len configs configs_size*sizeof(uint32_t)
+
+rcReadColorBuffer
+    dir pixels out
+    len pixels (((glUtilsPixelBitSize(format, type) * width) >> 3) * height)
+
+rcUpdateColorBuffer
+    dir pixels in
+    len pixels (((glUtilsPixelBitSize(format, type) * width) >> 3) * height)
+    var_flag pixels isLarge
diff --git a/opengl/system/renderControl_enc/renderControl.in b/opengl/system/renderControl_enc/renderControl.in
new file mode 100644
index 0000000..8281fd9
--- /dev/null
+++ b/opengl/system/renderControl_enc/renderControl.in
@@ -0,0 +1,25 @@
+GL_ENRTY(GLint, rcGetRendererVersion)
+GL_ENTRY(EGLint, rcGetEGLVersion, EGLint *major, EGLint *minor)
+GL_ENTRY(EGLint, rcQueryEGLString, EGLenum name, void *buffer, EGLint bufferSize)
+GL_ENTRY(EGLint, rcGetGLString, EGLenum name, void *buffer, EGLint bufferSize)
+GL_ENTRY(EGLint, rcGetNumConfigs, uint32_t *numAttribs)
+GL_ENTRY(EGLint, rcGetConfigs, uint32_t bufSize, GLuint *buffer)
+GL_ENTRY(EGLint, rcChooseConfig, EGLint *attribs, uint32_t attribs_size, uint32_t *configs, uint32_t configs_size)
+GL_ENTRY(EGLint, rcGetFBParam, EGLint param)
+GL_ENTRY(uint32_t, rcCreateContext, uint32_t config, uint32_t share, uint32_t glVersion)
+GL_ENTRY(void, rcDestroyContext, uint32_t context)
+GL_ENTRY(uint32_t, rcCreateWindowSurface, uint32_t config, uint32_t width, uint32_t height)
+GL_ENTRY(void, rcDestroyWindowSurface, uint32_t windowSurface)
+GL_ENTRY(uint32_t, rcCreateColorBuffer, uint32_t width, uint32_t height, GLenum internalFormat)
+GL_ENTRY(void, rcOpenColorBuffer, uint32_t colorbuffer)
+GL_ENTRY(void, rcCloseColorBuffer, uint32_t colorbuffer)
+GL_ENTRY(void, rcSetWindowColorBuffer, uint32_t windowSurface, uint32_t colorBuffer)
+GL_ENTRY(int, rcFlushWindowColorBuffer, uint32_t windowSurface)
+GL_ENTRY(EGLint, rcMakeCurrent, uint32_t context, uint32_t drawSurf, uint32_t readSurf)
+GL_ENTRY(void, rcFBPost, uint32_t colorBuffer)
+GL_ENTRY(void, rcFBSetSwapInterval, EGLint interval)
+GL_ENTRY(void, rcBindTexture, uint32_t colorBuffer)
+GL_ENTRY(void, rcBindRenderbuffer, uint32_t colorBuffer)
+GL_ENTRY(EGLint, rcColorBufferCacheFlush, uint32_t colorbuffer, EGLint postCount,int forRead)
+GL_ENTRY(void, rcReadColorBuffer, uint32_t colorbuffer, GLint x, GLint y, GLint width, GLint height, GLenum format, GLenum type, void *pixels)
+GL_ENTRY(int, rcUpdateColorBuffer, uint32_t colorbuffer, GLint x, GLint y, GLint width, GLint height, GLenum format, GLenum type, void *pixels)
diff --git a/opengl/system/renderControl_enc/renderControl.types b/opengl/system/renderControl_enc/renderControl.types
new file mode 100644
index 0000000..a7d96ab
--- /dev/null
+++ b/opengl/system/renderControl_enc/renderControl.types
@@ -0,0 +1,11 @@
+uint32_t 32 0x%08x false
+EGLint 32 0x%08x false
+GLint 32 0x%08x false
+GLuint 32 0x%08x false
+GLenum 32 0x%08x false
+EGLenum 32 0x%08x false
+uint32_t* 32 0x%08x true
+EGLint* 32 0x%08x true
+GLint* 32 0x%08x true
+GLuint* 32 0x%08x true
+void* 32 0x%08x true
diff --git a/opengl/system/renderControl_enc/renderControl_client_context.cpp b/opengl/system/renderControl_enc/renderControl_client_context.cpp
new file mode 100644
index 0000000..9488248
--- /dev/null
+++ b/opengl/system/renderControl_enc/renderControl_client_context.cpp
@@ -0,0 +1,42 @@
+// Generated Code - DO NOT EDIT !!
+// generated by 'emugen'
+
+
+#include <string.h>
+#include "renderControl_client_context.h"
+
+
+#include <stdio.h>
+
+int renderControl_client_context_t::initDispatchByName(void *(*getProc)(const char *, void *userData), void *userData)
+{
+	void *ptr;
+
+	ptr = getProc("rcGetRendererVersion", userData); set_rcGetRendererVersion((rcGetRendererVersion_client_proc_t)ptr);
+	ptr = getProc("rcGetEGLVersion", userData); set_rcGetEGLVersion((rcGetEGLVersion_client_proc_t)ptr);
+	ptr = getProc("rcQueryEGLString", userData); set_rcQueryEGLString((rcQueryEGLString_client_proc_t)ptr);
+	ptr = getProc("rcGetGLString", userData); set_rcGetGLString((rcGetGLString_client_proc_t)ptr);
+	ptr = getProc("rcGetNumConfigs", userData); set_rcGetNumConfigs((rcGetNumConfigs_client_proc_t)ptr);
+	ptr = getProc("rcGetConfigs", userData); set_rcGetConfigs((rcGetConfigs_client_proc_t)ptr);
+	ptr = getProc("rcChooseConfig", userData); set_rcChooseConfig((rcChooseConfig_client_proc_t)ptr);
+	ptr = getProc("rcGetFBParam", userData); set_rcGetFBParam((rcGetFBParam_client_proc_t)ptr);
+	ptr = getProc("rcCreateContext", userData); set_rcCreateContext((rcCreateContext_client_proc_t)ptr);
+	ptr = getProc("rcDestroyContext", userData); set_rcDestroyContext((rcDestroyContext_client_proc_t)ptr);
+	ptr = getProc("rcCreateWindowSurface", userData); set_rcCreateWindowSurface((rcCreateWindowSurface_client_proc_t)ptr);
+	ptr = getProc("rcDestroyWindowSurface", userData); set_rcDestroyWindowSurface((rcDestroyWindowSurface_client_proc_t)ptr);
+	ptr = getProc("rcCreateColorBuffer", userData); set_rcCreateColorBuffer((rcCreateColorBuffer_client_proc_t)ptr);
+	ptr = getProc("rcOpenColorBuffer", userData); set_rcOpenColorBuffer((rcOpenColorBuffer_client_proc_t)ptr);
+	ptr = getProc("rcCloseColorBuffer", userData); set_rcCloseColorBuffer((rcCloseColorBuffer_client_proc_t)ptr);
+	ptr = getProc("rcSetWindowColorBuffer", userData); set_rcSetWindowColorBuffer((rcSetWindowColorBuffer_client_proc_t)ptr);
+	ptr = getProc("rcFlushWindowColorBuffer", userData); set_rcFlushWindowColorBuffer((rcFlushWindowColorBuffer_client_proc_t)ptr);
+	ptr = getProc("rcMakeCurrent", userData); set_rcMakeCurrent((rcMakeCurrent_client_proc_t)ptr);
+	ptr = getProc("rcFBPost", userData); set_rcFBPost((rcFBPost_client_proc_t)ptr);
+	ptr = getProc("rcFBSetSwapInterval", userData); set_rcFBSetSwapInterval((rcFBSetSwapInterval_client_proc_t)ptr);
+	ptr = getProc("rcBindTexture", userData); set_rcBindTexture((rcBindTexture_client_proc_t)ptr);
+	ptr = getProc("rcBindRenderbuffer", userData); set_rcBindRenderbuffer((rcBindRenderbuffer_client_proc_t)ptr);
+	ptr = getProc("rcColorBufferCacheFlush", userData); set_rcColorBufferCacheFlush((rcColorBufferCacheFlush_client_proc_t)ptr);
+	ptr = getProc("rcReadColorBuffer", userData); set_rcReadColorBuffer((rcReadColorBuffer_client_proc_t)ptr);
+	ptr = getProc("rcUpdateColorBuffer", userData); set_rcUpdateColorBuffer((rcUpdateColorBuffer_client_proc_t)ptr);
+	return 0;
+}
+
diff --git a/opengl/system/renderControl_enc/renderControl_client_context.h b/opengl/system/renderControl_enc/renderControl_client_context.h
new file mode 100644
index 0000000..ed2b1fb
--- /dev/null
+++ b/opengl/system/renderControl_enc/renderControl_client_context.h
@@ -0,0 +1,71 @@
+// Generated Code - DO NOT EDIT !!
+// generated by 'emugen'
+#ifndef __renderControl_client_context_t_h
+#define __renderControl_client_context_t_h
+
+#include "renderControl_client_proc.h"
+
+
+struct renderControl_client_context_t {
+
+	rcGetRendererVersion_client_proc_t rcGetRendererVersion;
+	rcGetEGLVersion_client_proc_t rcGetEGLVersion;
+	rcQueryEGLString_client_proc_t rcQueryEGLString;
+	rcGetGLString_client_proc_t rcGetGLString;
+	rcGetNumConfigs_client_proc_t rcGetNumConfigs;
+	rcGetConfigs_client_proc_t rcGetConfigs;
+	rcChooseConfig_client_proc_t rcChooseConfig;
+	rcGetFBParam_client_proc_t rcGetFBParam;
+	rcCreateContext_client_proc_t rcCreateContext;
+	rcDestroyContext_client_proc_t rcDestroyContext;
+	rcCreateWindowSurface_client_proc_t rcCreateWindowSurface;
+	rcDestroyWindowSurface_client_proc_t rcDestroyWindowSurface;
+	rcCreateColorBuffer_client_proc_t rcCreateColorBuffer;
+	rcOpenColorBuffer_client_proc_t rcOpenColorBuffer;
+	rcCloseColorBuffer_client_proc_t rcCloseColorBuffer;
+	rcSetWindowColorBuffer_client_proc_t rcSetWindowColorBuffer;
+	rcFlushWindowColorBuffer_client_proc_t rcFlushWindowColorBuffer;
+	rcMakeCurrent_client_proc_t rcMakeCurrent;
+	rcFBPost_client_proc_t rcFBPost;
+	rcFBSetSwapInterval_client_proc_t rcFBSetSwapInterval;
+	rcBindTexture_client_proc_t rcBindTexture;
+	rcBindRenderbuffer_client_proc_t rcBindRenderbuffer;
+	rcColorBufferCacheFlush_client_proc_t rcColorBufferCacheFlush;
+	rcReadColorBuffer_client_proc_t rcReadColorBuffer;
+	rcUpdateColorBuffer_client_proc_t rcUpdateColorBuffer;
+	//Accessors 
+	virtual rcGetRendererVersion_client_proc_t set_rcGetRendererVersion(rcGetRendererVersion_client_proc_t f) { rcGetRendererVersion_client_proc_t retval = rcGetRendererVersion; rcGetRendererVersion = f; return retval;}
+	virtual rcGetEGLVersion_client_proc_t set_rcGetEGLVersion(rcGetEGLVersion_client_proc_t f) { rcGetEGLVersion_client_proc_t retval = rcGetEGLVersion; rcGetEGLVersion = f; return retval;}
+	virtual rcQueryEGLString_client_proc_t set_rcQueryEGLString(rcQueryEGLString_client_proc_t f) { rcQueryEGLString_client_proc_t retval = rcQueryEGLString; rcQueryEGLString = f; return retval;}
+	virtual rcGetGLString_client_proc_t set_rcGetGLString(rcGetGLString_client_proc_t f) { rcGetGLString_client_proc_t retval = rcGetGLString; rcGetGLString = f; return retval;}
+	virtual rcGetNumConfigs_client_proc_t set_rcGetNumConfigs(rcGetNumConfigs_client_proc_t f) { rcGetNumConfigs_client_proc_t retval = rcGetNumConfigs; rcGetNumConfigs = f; return retval;}
+	virtual rcGetConfigs_client_proc_t set_rcGetConfigs(rcGetConfigs_client_proc_t f) { rcGetConfigs_client_proc_t retval = rcGetConfigs; rcGetConfigs = f; return retval;}
+	virtual rcChooseConfig_client_proc_t set_rcChooseConfig(rcChooseConfig_client_proc_t f) { rcChooseConfig_client_proc_t retval = rcChooseConfig; rcChooseConfig = f; return retval;}
+	virtual rcGetFBParam_client_proc_t set_rcGetFBParam(rcGetFBParam_client_proc_t f) { rcGetFBParam_client_proc_t retval = rcGetFBParam; rcGetFBParam = f; return retval;}
+	virtual rcCreateContext_client_proc_t set_rcCreateContext(rcCreateContext_client_proc_t f) { rcCreateContext_client_proc_t retval = rcCreateContext; rcCreateContext = f; return retval;}
+	virtual rcDestroyContext_client_proc_t set_rcDestroyContext(rcDestroyContext_client_proc_t f) { rcDestroyContext_client_proc_t retval = rcDestroyContext; rcDestroyContext = f; return retval;}
+	virtual rcCreateWindowSurface_client_proc_t set_rcCreateWindowSurface(rcCreateWindowSurface_client_proc_t f) { rcCreateWindowSurface_client_proc_t retval = rcCreateWindowSurface; rcCreateWindowSurface = f; return retval;}
+	virtual rcDestroyWindowSurface_client_proc_t set_rcDestroyWindowSurface(rcDestroyWindowSurface_client_proc_t f) { rcDestroyWindowSurface_client_proc_t retval = rcDestroyWindowSurface; rcDestroyWindowSurface = f; return retval;}
+	virtual rcCreateColorBuffer_client_proc_t set_rcCreateColorBuffer(rcCreateColorBuffer_client_proc_t f) { rcCreateColorBuffer_client_proc_t retval = rcCreateColorBuffer; rcCreateColorBuffer = f; return retval;}
+	virtual rcOpenColorBuffer_client_proc_t set_rcOpenColorBuffer(rcOpenColorBuffer_client_proc_t f) { rcOpenColorBuffer_client_proc_t retval = rcOpenColorBuffer; rcOpenColorBuffer = f; return retval;}
+	virtual rcCloseColorBuffer_client_proc_t set_rcCloseColorBuffer(rcCloseColorBuffer_client_proc_t f) { rcCloseColorBuffer_client_proc_t retval = rcCloseColorBuffer; rcCloseColorBuffer = f; return retval;}
+	virtual rcSetWindowColorBuffer_client_proc_t set_rcSetWindowColorBuffer(rcSetWindowColorBuffer_client_proc_t f) { rcSetWindowColorBuffer_client_proc_t retval = rcSetWindowColorBuffer; rcSetWindowColorBuffer = f; return retval;}
+	virtual rcFlushWindowColorBuffer_client_proc_t set_rcFlushWindowColorBuffer(rcFlushWindowColorBuffer_client_proc_t f) { rcFlushWindowColorBuffer_client_proc_t retval = rcFlushWindowColorBuffer; rcFlushWindowColorBuffer = f; return retval;}
+	virtual rcMakeCurrent_client_proc_t set_rcMakeCurrent(rcMakeCurrent_client_proc_t f) { rcMakeCurrent_client_proc_t retval = rcMakeCurrent; rcMakeCurrent = f; return retval;}
+	virtual rcFBPost_client_proc_t set_rcFBPost(rcFBPost_client_proc_t f) { rcFBPost_client_proc_t retval = rcFBPost; rcFBPost = f; return retval;}
+	virtual rcFBSetSwapInterval_client_proc_t set_rcFBSetSwapInterval(rcFBSetSwapInterval_client_proc_t f) { rcFBSetSwapInterval_client_proc_t retval = rcFBSetSwapInterval; rcFBSetSwapInterval = f; return retval;}
+	virtual rcBindTexture_client_proc_t set_rcBindTexture(rcBindTexture_client_proc_t f) { rcBindTexture_client_proc_t retval = rcBindTexture; rcBindTexture = f; return retval;}
+	virtual rcBindRenderbuffer_client_proc_t set_rcBindRenderbuffer(rcBindRenderbuffer_client_proc_t f) { rcBindRenderbuffer_client_proc_t retval = rcBindRenderbuffer; rcBindRenderbuffer = f; return retval;}
+	virtual rcColorBufferCacheFlush_client_proc_t set_rcColorBufferCacheFlush(rcColorBufferCacheFlush_client_proc_t f) { rcColorBufferCacheFlush_client_proc_t retval = rcColorBufferCacheFlush; rcColorBufferCacheFlush = f; return retval;}
+	virtual rcReadColorBuffer_client_proc_t set_rcReadColorBuffer(rcReadColorBuffer_client_proc_t f) { rcReadColorBuffer_client_proc_t retval = rcReadColorBuffer; rcReadColorBuffer = f; return retval;}
+	virtual rcUpdateColorBuffer_client_proc_t set_rcUpdateColorBuffer(rcUpdateColorBuffer_client_proc_t f) { rcUpdateColorBuffer_client_proc_t retval = rcUpdateColorBuffer; rcUpdateColorBuffer = f; return retval;}
+	 virtual ~renderControl_client_context_t() {}
+
+	typedef renderControl_client_context_t *CONTEXT_ACCESSOR_TYPE(void);
+	static void setContextAccessor(CONTEXT_ACCESSOR_TYPE *f);
+	int initDispatchByName( void *(*getProc)(const char *name, void *userData), void *userData);
+	virtual void setError(unsigned int  error){};
+	virtual unsigned int getError(){ return 0; };
+};
+
+#endif
diff --git a/opengl/system/renderControl_enc/renderControl_client_proc.h b/opengl/system/renderControl_enc/renderControl_client_proc.h
new file mode 100644
index 0000000..3e00290
--- /dev/null
+++ b/opengl/system/renderControl_enc/renderControl_client_proc.h
@@ -0,0 +1,39 @@
+// Generated Code - DO NOT EDIT !!
+// generated by 'emugen'
+#ifndef __renderControl_client_proc_t_h
+#define __renderControl_client_proc_t_h
+
+
+
+#include "renderControl_types.h"
+#ifndef renderControl_APIENTRY
+#define renderControl_APIENTRY 
+#endif
+typedef GLint (renderControl_APIENTRY *rcGetRendererVersion_client_proc_t) (void * ctx);
+typedef EGLint (renderControl_APIENTRY *rcGetEGLVersion_client_proc_t) (void * ctx, EGLint*, EGLint*);
+typedef EGLint (renderControl_APIENTRY *rcQueryEGLString_client_proc_t) (void * ctx, EGLenum, void*, EGLint);
+typedef EGLint (renderControl_APIENTRY *rcGetGLString_client_proc_t) (void * ctx, EGLenum, void*, EGLint);
+typedef EGLint (renderControl_APIENTRY *rcGetNumConfigs_client_proc_t) (void * ctx, uint32_t*);
+typedef EGLint (renderControl_APIENTRY *rcGetConfigs_client_proc_t) (void * ctx, uint32_t, GLuint*);
+typedef EGLint (renderControl_APIENTRY *rcChooseConfig_client_proc_t) (void * ctx, EGLint*, uint32_t, uint32_t*, uint32_t);
+typedef EGLint (renderControl_APIENTRY *rcGetFBParam_client_proc_t) (void * ctx, EGLint);
+typedef uint32_t (renderControl_APIENTRY *rcCreateContext_client_proc_t) (void * ctx, uint32_t, uint32_t, uint32_t);
+typedef void (renderControl_APIENTRY *rcDestroyContext_client_proc_t) (void * ctx, uint32_t);
+typedef uint32_t (renderControl_APIENTRY *rcCreateWindowSurface_client_proc_t) (void * ctx, uint32_t, uint32_t, uint32_t);
+typedef void (renderControl_APIENTRY *rcDestroyWindowSurface_client_proc_t) (void * ctx, uint32_t);
+typedef uint32_t (renderControl_APIENTRY *rcCreateColorBuffer_client_proc_t) (void * ctx, uint32_t, uint32_t, GLenum);
+typedef void (renderControl_APIENTRY *rcOpenColorBuffer_client_proc_t) (void * ctx, uint32_t);
+typedef void (renderControl_APIENTRY *rcCloseColorBuffer_client_proc_t) (void * ctx, uint32_t);
+typedef void (renderControl_APIENTRY *rcSetWindowColorBuffer_client_proc_t) (void * ctx, uint32_t, uint32_t);
+typedef int (renderControl_APIENTRY *rcFlushWindowColorBuffer_client_proc_t) (void * ctx, uint32_t);
+typedef EGLint (renderControl_APIENTRY *rcMakeCurrent_client_proc_t) (void * ctx, uint32_t, uint32_t, uint32_t);
+typedef void (renderControl_APIENTRY *rcFBPost_client_proc_t) (void * ctx, uint32_t);
+typedef void (renderControl_APIENTRY *rcFBSetSwapInterval_client_proc_t) (void * ctx, EGLint);
+typedef void (renderControl_APIENTRY *rcBindTexture_client_proc_t) (void * ctx, uint32_t);
+typedef void (renderControl_APIENTRY *rcBindRenderbuffer_client_proc_t) (void * ctx, uint32_t);
+typedef EGLint (renderControl_APIENTRY *rcColorBufferCacheFlush_client_proc_t) (void * ctx, uint32_t, EGLint, int);
+typedef void (renderControl_APIENTRY *rcReadColorBuffer_client_proc_t) (void * ctx, uint32_t, GLint, GLint, GLint, GLint, GLenum, GLenum, void*);
+typedef int (renderControl_APIENTRY *rcUpdateColorBuffer_client_proc_t) (void * ctx, uint32_t, GLint, GLint, GLint, GLint, GLenum, GLenum, void*);
+
+
+#endif
diff --git a/opengl/system/renderControl_enc/renderControl_enc.cpp b/opengl/system/renderControl_enc/renderControl_enc.cpp
new file mode 100644
index 0000000..94e256a
--- /dev/null
+++ b/opengl/system/renderControl_enc/renderControl_enc.cpp
@@ -0,0 +1,536 @@
+// Generated Code - DO NOT EDIT !!
+// generated by 'emugen'
+
+
+#include <string.h>
+#include "renderControl_opcodes.h"
+
+#include "renderControl_enc.h"
+
+
+#include <stdio.h>
+static void enc_unsupported()
+{
+	ALOGE("Function is unsupported\n");
+}
+
+GLint rcGetRendererVersion_enc(void *self )
+{
+
+	renderControl_encoder_context_t *ctx = (renderControl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_rcGetRendererVersion;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+
+	GLint retval;
+	stream->readback(&retval, 4);
+	return retval;
+}
+
+EGLint rcGetEGLVersion_enc(void *self , EGLint* major, EGLint* minor)
+{
+
+	renderControl_encoder_context_t *ctx = (renderControl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_major =  sizeof(EGLint);
+	const unsigned int __size_minor =  sizeof(EGLint);
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + __size_major + __size_minor + 2*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_rcGetEGLVersion;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+	*(unsigned int *)(ptr) = __size_major; ptr += 4;
+	*(unsigned int *)(ptr) = __size_minor; ptr += 4;
+	stream->readback(major, __size_major);
+	stream->readback(minor, __size_minor);
+
+	EGLint retval;
+	stream->readback(&retval, 4);
+	return retval;
+}
+
+EGLint rcQueryEGLString_enc(void *self , EGLenum name, void* buffer, EGLint bufferSize)
+{
+
+	renderControl_encoder_context_t *ctx = (renderControl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_buffer =  bufferSize;
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_buffer + 4 + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_rcQueryEGLString;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &name, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_buffer; ptr += 4;
+		memcpy(ptr, &bufferSize, 4); ptr += 4;
+	stream->readback(buffer, __size_buffer);
+
+	EGLint retval;
+	stream->readback(&retval, 4);
+	return retval;
+}
+
+EGLint rcGetGLString_enc(void *self , EGLenum name, void* buffer, EGLint bufferSize)
+{
+
+	renderControl_encoder_context_t *ctx = (renderControl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_buffer =  bufferSize;
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_buffer + 4 + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_rcGetGLString;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &name, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_buffer; ptr += 4;
+		memcpy(ptr, &bufferSize, 4); ptr += 4;
+	stream->readback(buffer, __size_buffer);
+
+	EGLint retval;
+	stream->readback(&retval, 4);
+	return retval;
+}
+
+EGLint rcGetNumConfigs_enc(void *self , uint32_t* numAttribs)
+{
+
+	renderControl_encoder_context_t *ctx = (renderControl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_numAttribs =  sizeof(uint32_t);
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + __size_numAttribs + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_rcGetNumConfigs;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+	*(unsigned int *)(ptr) = __size_numAttribs; ptr += 4;
+	stream->readback(numAttribs, __size_numAttribs);
+
+	EGLint retval;
+	stream->readback(&retval, 4);
+	return retval;
+}
+
+EGLint rcGetConfigs_enc(void *self , uint32_t bufSize, GLuint* buffer)
+{
+
+	renderControl_encoder_context_t *ctx = (renderControl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_buffer =  bufSize;
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + __size_buffer + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_rcGetConfigs;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &bufSize, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_buffer; ptr += 4;
+	stream->readback(buffer, __size_buffer);
+
+	EGLint retval;
+	stream->readback(&retval, 4);
+	return retval;
+}
+
+EGLint rcChooseConfig_enc(void *self , EGLint* attribs, uint32_t attribs_size, uint32_t* configs, uint32_t configs_size)
+{
+
+	renderControl_encoder_context_t *ctx = (renderControl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_attribs =  attribs_size;
+	const unsigned int __size_configs = ((configs != NULL) ?  configs_size*sizeof(uint32_t) : 0);
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + __size_attribs + 4 + __size_configs + 4 + 2*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_rcChooseConfig;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+	*(unsigned int *)(ptr) = __size_attribs; ptr += 4;
+	memcpy(ptr, attribs, __size_attribs);ptr += __size_attribs;
+		memcpy(ptr, &attribs_size, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_configs; ptr += 4;
+		memcpy(ptr, &configs_size, 4); ptr += 4;
+	if (configs != NULL) stream->readback(configs, __size_configs);
+
+	EGLint retval;
+	stream->readback(&retval, 4);
+	return retval;
+}
+
+EGLint rcGetFBParam_enc(void *self , EGLint param)
+{
+
+	renderControl_encoder_context_t *ctx = (renderControl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_rcGetFBParam;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &param, 4); ptr += 4;
+
+	EGLint retval;
+	stream->readback(&retval, 4);
+	return retval;
+}
+
+uint32_t rcCreateContext_enc(void *self , uint32_t config, uint32_t share, uint32_t glVersion)
+{
+
+	renderControl_encoder_context_t *ctx = (renderControl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_rcCreateContext;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &config, 4); ptr += 4;
+		memcpy(ptr, &share, 4); ptr += 4;
+		memcpy(ptr, &glVersion, 4); ptr += 4;
+
+	uint32_t retval;
+	stream->readback(&retval, 4);
+	return retval;
+}
+
+void rcDestroyContext_enc(void *self , uint32_t context)
+{
+
+	renderControl_encoder_context_t *ctx = (renderControl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_rcDestroyContext;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &context, 4); ptr += 4;
+}
+
+uint32_t rcCreateWindowSurface_enc(void *self , uint32_t config, uint32_t width, uint32_t height)
+{
+
+	renderControl_encoder_context_t *ctx = (renderControl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_rcCreateWindowSurface;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &config, 4); ptr += 4;
+		memcpy(ptr, &width, 4); ptr += 4;
+		memcpy(ptr, &height, 4); ptr += 4;
+
+	uint32_t retval;
+	stream->readback(&retval, 4);
+	return retval;
+}
+
+void rcDestroyWindowSurface_enc(void *self , uint32_t windowSurface)
+{
+
+	renderControl_encoder_context_t *ctx = (renderControl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_rcDestroyWindowSurface;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &windowSurface, 4); ptr += 4;
+}
+
+uint32_t rcCreateColorBuffer_enc(void *self , uint32_t width, uint32_t height, GLenum internalFormat)
+{
+
+	renderControl_encoder_context_t *ctx = (renderControl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_rcCreateColorBuffer;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &width, 4); ptr += 4;
+		memcpy(ptr, &height, 4); ptr += 4;
+		memcpy(ptr, &internalFormat, 4); ptr += 4;
+
+	uint32_t retval;
+	stream->readback(&retval, 4);
+	return retval;
+}
+
+void rcOpenColorBuffer_enc(void *self , uint32_t colorbuffer)
+{
+
+	renderControl_encoder_context_t *ctx = (renderControl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_rcOpenColorBuffer;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &colorbuffer, 4); ptr += 4;
+}
+
+void rcCloseColorBuffer_enc(void *self , uint32_t colorbuffer)
+{
+
+	renderControl_encoder_context_t *ctx = (renderControl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_rcCloseColorBuffer;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &colorbuffer, 4); ptr += 4;
+}
+
+void rcSetWindowColorBuffer_enc(void *self , uint32_t windowSurface, uint32_t colorBuffer)
+{
+
+	renderControl_encoder_context_t *ctx = (renderControl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_rcSetWindowColorBuffer;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &windowSurface, 4); ptr += 4;
+		memcpy(ptr, &colorBuffer, 4); ptr += 4;
+}
+
+int rcFlushWindowColorBuffer_enc(void *self , uint32_t windowSurface)
+{
+
+	renderControl_encoder_context_t *ctx = (renderControl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_rcFlushWindowColorBuffer;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &windowSurface, 4); ptr += 4;
+
+	int retval;
+	stream->readback(&retval, 4);
+	return retval;
+}
+
+EGLint rcMakeCurrent_enc(void *self , uint32_t context, uint32_t drawSurf, uint32_t readSurf)
+{
+
+	renderControl_encoder_context_t *ctx = (renderControl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_rcMakeCurrent;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &context, 4); ptr += 4;
+		memcpy(ptr, &drawSurf, 4); ptr += 4;
+		memcpy(ptr, &readSurf, 4); ptr += 4;
+
+	EGLint retval;
+	stream->readback(&retval, 4);
+	return retval;
+}
+
+void rcFBPost_enc(void *self , uint32_t colorBuffer)
+{
+
+	renderControl_encoder_context_t *ctx = (renderControl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_rcFBPost;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &colorBuffer, 4); ptr += 4;
+}
+
+void rcFBSetSwapInterval_enc(void *self , EGLint interval)
+{
+
+	renderControl_encoder_context_t *ctx = (renderControl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_rcFBSetSwapInterval;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &interval, 4); ptr += 4;
+}
+
+void rcBindTexture_enc(void *self , uint32_t colorBuffer)
+{
+
+	renderControl_encoder_context_t *ctx = (renderControl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_rcBindTexture;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &colorBuffer, 4); ptr += 4;
+}
+
+void rcBindRenderbuffer_enc(void *self , uint32_t colorBuffer)
+{
+
+	renderControl_encoder_context_t *ctx = (renderControl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_rcBindRenderbuffer;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &colorBuffer, 4); ptr += 4;
+}
+
+EGLint rcColorBufferCacheFlush_enc(void *self , uint32_t colorbuffer, EGLint postCount, int forRead)
+{
+
+	renderControl_encoder_context_t *ctx = (renderControl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_rcColorBufferCacheFlush;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &colorbuffer, 4); ptr += 4;
+		memcpy(ptr, &postCount, 4); ptr += 4;
+		memcpy(ptr, &forRead, 4); ptr += 4;
+
+	EGLint retval;
+	stream->readback(&retval, 4);
+	return retval;
+}
+
+void rcReadColorBuffer_enc(void *self , uint32_t colorbuffer, GLint x, GLint y, GLint width, GLint height, GLenum format, GLenum type, void* pixels)
+{
+
+	renderControl_encoder_context_t *ctx = (renderControl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_pixels =  (((glUtilsPixelBitSize(format, type) * width) >> 3) * height);
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + __size_pixels + 1*4;
+	ptr = stream->alloc(packetSize);
+	int tmp = OP_rcReadColorBuffer;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &colorbuffer, 4); ptr += 4;
+		memcpy(ptr, &x, 4); ptr += 4;
+		memcpy(ptr, &y, 4); ptr += 4;
+		memcpy(ptr, &width, 4); ptr += 4;
+		memcpy(ptr, &height, 4); ptr += 4;
+		memcpy(ptr, &format, 4); ptr += 4;
+		memcpy(ptr, &type, 4); ptr += 4;
+	*(unsigned int *)(ptr) = __size_pixels; ptr += 4;
+	stream->readback(pixels, __size_pixels);
+}
+
+int rcUpdateColorBuffer_enc(void *self , uint32_t colorbuffer, GLint x, GLint y, GLint width, GLint height, GLenum format, GLenum type, void* pixels)
+{
+
+	renderControl_encoder_context_t *ctx = (renderControl_encoder_context_t *)self;
+	IOStream *stream = ctx->m_stream;
+
+	const unsigned int __size_pixels =  (((glUtilsPixelBitSize(format, type) * width) >> 3) * height);
+	 unsigned char *ptr;
+	 const size_t packetSize = 8 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + __size_pixels + 1*4;
+	ptr = stream->alloc(8 + 4 + 4 + 4 + 4 + 4 + 4 + 4);
+	int tmp = OP_rcUpdateColorBuffer;memcpy(ptr, &tmp, 4); ptr += 4;
+	memcpy(ptr, &packetSize, 4);  ptr += 4;
+
+		memcpy(ptr, &colorbuffer, 4); ptr += 4;
+		memcpy(ptr, &x, 4); ptr += 4;
+		memcpy(ptr, &y, 4); ptr += 4;
+		memcpy(ptr, &width, 4); ptr += 4;
+		memcpy(ptr, &height, 4); ptr += 4;
+		memcpy(ptr, &format, 4); ptr += 4;
+		memcpy(ptr, &type, 4); ptr += 4;
+	stream->flush();
+	stream->writeFully(&__size_pixels,4);
+	stream->writeFully(pixels, __size_pixels);
+
+	int retval;
+	stream->readback(&retval, 4);
+	return retval;
+}
+
+renderControl_encoder_context_t::renderControl_encoder_context_t(IOStream *stream)
+{
+	m_stream = stream;
+
+	set_rcGetRendererVersion(rcGetRendererVersion_enc);
+	set_rcGetEGLVersion(rcGetEGLVersion_enc);
+	set_rcQueryEGLString(rcQueryEGLString_enc);
+	set_rcGetGLString(rcGetGLString_enc);
+	set_rcGetNumConfigs(rcGetNumConfigs_enc);
+	set_rcGetConfigs(rcGetConfigs_enc);
+	set_rcChooseConfig(rcChooseConfig_enc);
+	set_rcGetFBParam(rcGetFBParam_enc);
+	set_rcCreateContext(rcCreateContext_enc);
+	set_rcDestroyContext(rcDestroyContext_enc);
+	set_rcCreateWindowSurface(rcCreateWindowSurface_enc);
+	set_rcDestroyWindowSurface(rcDestroyWindowSurface_enc);
+	set_rcCreateColorBuffer(rcCreateColorBuffer_enc);
+	set_rcOpenColorBuffer(rcOpenColorBuffer_enc);
+	set_rcCloseColorBuffer(rcCloseColorBuffer_enc);
+	set_rcSetWindowColorBuffer(rcSetWindowColorBuffer_enc);
+	set_rcFlushWindowColorBuffer(rcFlushWindowColorBuffer_enc);
+	set_rcMakeCurrent(rcMakeCurrent_enc);
+	set_rcFBPost(rcFBPost_enc);
+	set_rcFBSetSwapInterval(rcFBSetSwapInterval_enc);
+	set_rcBindTexture(rcBindTexture_enc);
+	set_rcBindRenderbuffer(rcBindRenderbuffer_enc);
+	set_rcColorBufferCacheFlush(rcColorBufferCacheFlush_enc);
+	set_rcReadColorBuffer(rcReadColorBuffer_enc);
+	set_rcUpdateColorBuffer(rcUpdateColorBuffer_enc);
+}
+
diff --git a/opengl/system/renderControl_enc/renderControl_enc.h b/opengl/system/renderControl_enc/renderControl_enc.h
new file mode 100644
index 0000000..712eeb9
--- /dev/null
+++ b/opengl/system/renderControl_enc/renderControl_enc.h
@@ -0,0 +1,51 @@
+// Generated Code - DO NOT EDIT !!
+// generated by 'emugen'
+
+#ifndef GUARD_renderControl_encoder_context_t
+#define GUARD_renderControl_encoder_context_t
+
+#include "IOStream.h"
+#include "renderControl_client_context.h"
+
+
+#include <stdint.h>
+#include <EGL/egl.h>
+#include "glUtils.h"
+
+struct renderControl_encoder_context_t : public renderControl_client_context_t {
+
+	IOStream *m_stream;
+
+	renderControl_encoder_context_t(IOStream *stream);
+
+
+};
+
+extern "C" {
+	GLint rcGetRendererVersion_enc(void *self );
+	EGLint rcGetEGLVersion_enc(void *self , EGLint* major, EGLint* minor);
+	EGLint rcQueryEGLString_enc(void *self , EGLenum name, void* buffer, EGLint bufferSize);
+	EGLint rcGetGLString_enc(void *self , EGLenum name, void* buffer, EGLint bufferSize);
+	EGLint rcGetNumConfigs_enc(void *self , uint32_t* numAttribs);
+	EGLint rcGetConfigs_enc(void *self , uint32_t bufSize, GLuint* buffer);
+	EGLint rcChooseConfig_enc(void *self , EGLint* attribs, uint32_t attribs_size, uint32_t* configs, uint32_t configs_size);
+	EGLint rcGetFBParam_enc(void *self , EGLint param);
+	uint32_t rcCreateContext_enc(void *self , uint32_t config, uint32_t share, uint32_t glVersion);
+	void rcDestroyContext_enc(void *self , uint32_t context);
+	uint32_t rcCreateWindowSurface_enc(void *self , uint32_t config, uint32_t width, uint32_t height);
+	void rcDestroyWindowSurface_enc(void *self , uint32_t windowSurface);
+	uint32_t rcCreateColorBuffer_enc(void *self , uint32_t width, uint32_t height, GLenum internalFormat);
+	void rcOpenColorBuffer_enc(void *self , uint32_t colorbuffer);
+	void rcCloseColorBuffer_enc(void *self , uint32_t colorbuffer);
+	void rcSetWindowColorBuffer_enc(void *self , uint32_t windowSurface, uint32_t colorBuffer);
+	int rcFlushWindowColorBuffer_enc(void *self , uint32_t windowSurface);
+	EGLint rcMakeCurrent_enc(void *self , uint32_t context, uint32_t drawSurf, uint32_t readSurf);
+	void rcFBPost_enc(void *self , uint32_t colorBuffer);
+	void rcFBSetSwapInterval_enc(void *self , EGLint interval);
+	void rcBindTexture_enc(void *self , uint32_t colorBuffer);
+	void rcBindRenderbuffer_enc(void *self , uint32_t colorBuffer);
+	EGLint rcColorBufferCacheFlush_enc(void *self , uint32_t colorbuffer, EGLint postCount, int forRead);
+	void rcReadColorBuffer_enc(void *self , uint32_t colorbuffer, GLint x, GLint y, GLint width, GLint height, GLenum format, GLenum type, void* pixels);
+	int rcUpdateColorBuffer_enc(void *self , uint32_t colorbuffer, GLint x, GLint y, GLint width, GLint height, GLenum format, GLenum type, void* pixels);
+};
+#endif
\ No newline at end of file
diff --git a/opengl/system/renderControl_enc/renderControl_entry.cpp b/opengl/system/renderControl_enc/renderControl_entry.cpp
new file mode 100644
index 0000000..9a0bba9
--- /dev/null
+++ b/opengl/system/renderControl_enc/renderControl_entry.cpp
@@ -0,0 +1,192 @@
+// Generated Code - DO NOT EDIT !!
+// generated by 'emugen'
+#include <stdio.h>
+#include <stdlib.h>
+#include "renderControl_client_context.h"
+
+#ifndef GL_TRUE
+extern "C" {
+	GLint rcGetRendererVersion();
+	EGLint rcGetEGLVersion(EGLint* major, EGLint* minor);
+	EGLint rcQueryEGLString(EGLenum name, void* buffer, EGLint bufferSize);
+	EGLint rcGetGLString(EGLenum name, void* buffer, EGLint bufferSize);
+	EGLint rcGetNumConfigs(uint32_t* numAttribs);
+	EGLint rcGetConfigs(uint32_t bufSize, GLuint* buffer);
+	EGLint rcChooseConfig(EGLint* attribs, uint32_t attribs_size, uint32_t* configs, uint32_t configs_size);
+	EGLint rcGetFBParam(EGLint param);
+	uint32_t rcCreateContext(uint32_t config, uint32_t share, uint32_t glVersion);
+	void rcDestroyContext(uint32_t context);
+	uint32_t rcCreateWindowSurface(uint32_t config, uint32_t width, uint32_t height);
+	void rcDestroyWindowSurface(uint32_t windowSurface);
+	uint32_t rcCreateColorBuffer(uint32_t width, uint32_t height, GLenum internalFormat);
+	void rcOpenColorBuffer(uint32_t colorbuffer);
+	void rcCloseColorBuffer(uint32_t colorbuffer);
+	void rcSetWindowColorBuffer(uint32_t windowSurface, uint32_t colorBuffer);
+	int rcFlushWindowColorBuffer(uint32_t windowSurface);
+	EGLint rcMakeCurrent(uint32_t context, uint32_t drawSurf, uint32_t readSurf);
+	void rcFBPost(uint32_t colorBuffer);
+	void rcFBSetSwapInterval(EGLint interval);
+	void rcBindTexture(uint32_t colorBuffer);
+	void rcBindRenderbuffer(uint32_t colorBuffer);
+	EGLint rcColorBufferCacheFlush(uint32_t colorbuffer, EGLint postCount, int forRead);
+	void rcReadColorBuffer(uint32_t colorbuffer, GLint x, GLint y, GLint width, GLint height, GLenum format, GLenum type, void* pixels);
+	int rcUpdateColorBuffer(uint32_t colorbuffer, GLint x, GLint y, GLint width, GLint height, GLenum format, GLenum type, void* pixels);
+};
+
+#endif
+#ifndef GET_CONTEXT
+static renderControl_client_context_t::CONTEXT_ACCESSOR_TYPE *getCurrentContext = NULL;
+void renderControl_client_context_t::setContextAccessor(CONTEXT_ACCESSOR_TYPE *f) { getCurrentContext = f; }
+#define GET_CONTEXT renderControl_client_context_t * ctx = getCurrentContext() 
+#endif
+
+GLint rcGetRendererVersion()
+{
+	GET_CONTEXT; 
+	 return ctx->rcGetRendererVersion(ctx);
+}
+
+EGLint rcGetEGLVersion(EGLint* major, EGLint* minor)
+{
+	GET_CONTEXT; 
+	 return ctx->rcGetEGLVersion(ctx, major, minor);
+}
+
+EGLint rcQueryEGLString(EGLenum name, void* buffer, EGLint bufferSize)
+{
+	GET_CONTEXT; 
+	 return ctx->rcQueryEGLString(ctx, name, buffer, bufferSize);
+}
+
+EGLint rcGetGLString(EGLenum name, void* buffer, EGLint bufferSize)
+{
+	GET_CONTEXT; 
+	 return ctx->rcGetGLString(ctx, name, buffer, bufferSize);
+}
+
+EGLint rcGetNumConfigs(uint32_t* numAttribs)
+{
+	GET_CONTEXT; 
+	 return ctx->rcGetNumConfigs(ctx, numAttribs);
+}
+
+EGLint rcGetConfigs(uint32_t bufSize, GLuint* buffer)
+{
+	GET_CONTEXT; 
+	 return ctx->rcGetConfigs(ctx, bufSize, buffer);
+}
+
+EGLint rcChooseConfig(EGLint* attribs, uint32_t attribs_size, uint32_t* configs, uint32_t configs_size)
+{
+	GET_CONTEXT; 
+	 return ctx->rcChooseConfig(ctx, attribs, attribs_size, configs, configs_size);
+}
+
+EGLint rcGetFBParam(EGLint param)
+{
+	GET_CONTEXT; 
+	 return ctx->rcGetFBParam(ctx, param);
+}
+
+uint32_t rcCreateContext(uint32_t config, uint32_t share, uint32_t glVersion)
+{
+	GET_CONTEXT; 
+	 return ctx->rcCreateContext(ctx, config, share, glVersion);
+}
+
+void rcDestroyContext(uint32_t context)
+{
+	GET_CONTEXT; 
+	 ctx->rcDestroyContext(ctx, context);
+}
+
+uint32_t rcCreateWindowSurface(uint32_t config, uint32_t width, uint32_t height)
+{
+	GET_CONTEXT; 
+	 return ctx->rcCreateWindowSurface(ctx, config, width, height);
+}
+
+void rcDestroyWindowSurface(uint32_t windowSurface)
+{
+	GET_CONTEXT; 
+	 ctx->rcDestroyWindowSurface(ctx, windowSurface);
+}
+
+uint32_t rcCreateColorBuffer(uint32_t width, uint32_t height, GLenum internalFormat)
+{
+	GET_CONTEXT; 
+	 return ctx->rcCreateColorBuffer(ctx, width, height, internalFormat);
+}
+
+void rcOpenColorBuffer(uint32_t colorbuffer)
+{
+	GET_CONTEXT; 
+	 ctx->rcOpenColorBuffer(ctx, colorbuffer);
+}
+
+void rcCloseColorBuffer(uint32_t colorbuffer)
+{
+	GET_CONTEXT; 
+	 ctx->rcCloseColorBuffer(ctx, colorbuffer);
+}
+
+void rcSetWindowColorBuffer(uint32_t windowSurface, uint32_t colorBuffer)
+{
+	GET_CONTEXT; 
+	 ctx->rcSetWindowColorBuffer(ctx, windowSurface, colorBuffer);
+}
+
+int rcFlushWindowColorBuffer(uint32_t windowSurface)
+{
+	GET_CONTEXT; 
+	 return ctx->rcFlushWindowColorBuffer(ctx, windowSurface);
+}
+
+EGLint rcMakeCurrent(uint32_t context, uint32_t drawSurf, uint32_t readSurf)
+{
+	GET_CONTEXT; 
+	 return ctx->rcMakeCurrent(ctx, context, drawSurf, readSurf);
+}
+
+void rcFBPost(uint32_t colorBuffer)
+{
+	GET_CONTEXT; 
+	 ctx->rcFBPost(ctx, colorBuffer);
+}
+
+void rcFBSetSwapInterval(EGLint interval)
+{
+	GET_CONTEXT; 
+	 ctx->rcFBSetSwapInterval(ctx, interval);
+}
+
+void rcBindTexture(uint32_t colorBuffer)
+{
+	GET_CONTEXT; 
+	 ctx->rcBindTexture(ctx, colorBuffer);
+}
+
+void rcBindRenderbuffer(uint32_t colorBuffer)
+{
+	GET_CONTEXT; 
+	 ctx->rcBindRenderbuffer(ctx, colorBuffer);
+}
+
+EGLint rcColorBufferCacheFlush(uint32_t colorbuffer, EGLint postCount, int forRead)
+{
+	GET_CONTEXT; 
+	 return ctx->rcColorBufferCacheFlush(ctx, colorbuffer, postCount, forRead);
+}
+
+void rcReadColorBuffer(uint32_t colorbuffer, GLint x, GLint y, GLint width, GLint height, GLenum format, GLenum type, void* pixels)
+{
+	GET_CONTEXT; 
+	 ctx->rcReadColorBuffer(ctx, colorbuffer, x, y, width, height, format, type, pixels);
+}
+
+int rcUpdateColorBuffer(uint32_t colorbuffer, GLint x, GLint y, GLint width, GLint height, GLenum format, GLenum type, void* pixels)
+{
+	GET_CONTEXT; 
+	 return ctx->rcUpdateColorBuffer(ctx, colorbuffer, x, y, width, height, format, type, pixels);
+}
+
diff --git a/opengl/system/renderControl_enc/renderControl_ftable.h b/opengl/system/renderControl_enc/renderControl_ftable.h
new file mode 100644
index 0000000..1e9e2f9
--- /dev/null
+++ b/opengl/system/renderControl_enc/renderControl_ftable.h
@@ -0,0 +1,40 @@
+// Generated Code - DO NOT EDIT !!
+// generated by 'emugen'
+#ifndef __renderControl_client_ftable_t_h
+#define __renderControl_client_ftable_t_h
+
+
+static struct _renderControl_funcs_by_name {
+	const char *name;
+	void *proc;
+} renderControl_funcs_by_name[] = {
+	{"rcGetRendererVersion", (void*)rcGetRendererVersion},
+	{"rcGetEGLVersion", (void*)rcGetEGLVersion},
+	{"rcQueryEGLString", (void*)rcQueryEGLString},
+	{"rcGetGLString", (void*)rcGetGLString},
+	{"rcGetNumConfigs", (void*)rcGetNumConfigs},
+	{"rcGetConfigs", (void*)rcGetConfigs},
+	{"rcChooseConfig", (void*)rcChooseConfig},
+	{"rcGetFBParam", (void*)rcGetFBParam},
+	{"rcCreateContext", (void*)rcCreateContext},
+	{"rcDestroyContext", (void*)rcDestroyContext},
+	{"rcCreateWindowSurface", (void*)rcCreateWindowSurface},
+	{"rcDestroyWindowSurface", (void*)rcDestroyWindowSurface},
+	{"rcCreateColorBuffer", (void*)rcCreateColorBuffer},
+	{"rcOpenColorBuffer", (void*)rcOpenColorBuffer},
+	{"rcCloseColorBuffer", (void*)rcCloseColorBuffer},
+	{"rcSetWindowColorBuffer", (void*)rcSetWindowColorBuffer},
+	{"rcFlushWindowColorBuffer", (void*)rcFlushWindowColorBuffer},
+	{"rcMakeCurrent", (void*)rcMakeCurrent},
+	{"rcFBPost", (void*)rcFBPost},
+	{"rcFBSetSwapInterval", (void*)rcFBSetSwapInterval},
+	{"rcBindTexture", (void*)rcBindTexture},
+	{"rcBindRenderbuffer", (void*)rcBindRenderbuffer},
+	{"rcColorBufferCacheFlush", (void*)rcColorBufferCacheFlush},
+	{"rcReadColorBuffer", (void*)rcReadColorBuffer},
+	{"rcUpdateColorBuffer", (void*)rcUpdateColorBuffer},
+};
+static int renderControl_num_funcs = sizeof(renderControl_funcs_by_name) / sizeof(struct _renderControl_funcs_by_name);
+
+
+#endif
diff --git a/opengl/system/renderControl_enc/renderControl_opcodes.h b/opengl/system/renderControl_enc/renderControl_opcodes.h
new file mode 100644
index 0000000..b44f5d0
--- /dev/null
+++ b/opengl/system/renderControl_enc/renderControl_opcodes.h
@@ -0,0 +1,34 @@
+// Generated Code - DO NOT EDIT !!
+// generated by 'emugen'
+#ifndef __GUARD_renderControl_opcodes_h_
+#define __GUARD_renderControl_opcodes_h_
+
+#define OP_rcGetRendererVersion 					10000
+#define OP_rcGetEGLVersion 					10001
+#define OP_rcQueryEGLString 					10002
+#define OP_rcGetGLString 					10003
+#define OP_rcGetNumConfigs 					10004
+#define OP_rcGetConfigs 					10005
+#define OP_rcChooseConfig 					10006
+#define OP_rcGetFBParam 					10007
+#define OP_rcCreateContext 					10008
+#define OP_rcDestroyContext 					10009
+#define OP_rcCreateWindowSurface 					10010
+#define OP_rcDestroyWindowSurface 					10011
+#define OP_rcCreateColorBuffer 					10012
+#define OP_rcOpenColorBuffer 					10013
+#define OP_rcCloseColorBuffer 					10014
+#define OP_rcSetWindowColorBuffer 					10015
+#define OP_rcFlushWindowColorBuffer 					10016
+#define OP_rcMakeCurrent 					10017
+#define OP_rcFBPost 					10018
+#define OP_rcFBSetSwapInterval 					10019
+#define OP_rcBindTexture 					10020
+#define OP_rcBindRenderbuffer 					10021
+#define OP_rcColorBufferCacheFlush 					10022
+#define OP_rcReadColorBuffer 					10023
+#define OP_rcUpdateColorBuffer 					10024
+#define OP_last 					10025
+
+
+#endif
diff --git a/opengl/system/renderControl_enc/renderControl_types.h b/opengl/system/renderControl_enc/renderControl_types.h
new file mode 100644
index 0000000..da215bb
--- /dev/null
+++ b/opengl/system/renderControl_enc/renderControl_types.h
@@ -0,0 +1,28 @@
+/*
+* Copyright 2011 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.
+*/
+
+#include <stdint.h>
+#include <EGL/egl.h>
+#include "glUtils.h"
+
+// values for 'param' argument of rcGetFBParam
+#define FB_WIDTH    1
+#define FB_HEIGHT   2
+#define FB_XDPI     3
+#define FB_YDPI     4
+#define FB_FPS      5
+#define FB_MIN_SWAP_INTERVAL 6
+#define FB_MAX_SWAP_INTERVAL 7
diff --git a/opengl/tests/gles_android_wrapper/Android.mk b/opengl/tests/gles_android_wrapper/Android.mk
new file mode 100644
index 0000000..d97212d
--- /dev/null
+++ b/opengl/tests/gles_android_wrapper/Android.mk
@@ -0,0 +1,74 @@
+LOCAL_PATH := $(call my-dir)
+
+#### libGLESv1_CM_emul.so
+$(call emugl-begin-shared-library,libGLESv1_CM_emul)
+$(call emugl-import,libGLESv1_enc)
+$(call emugl-gen-wrapper,$(EMUGL_PATH)/system/GLESv1_enc,gl)
+$(call emugl-set-shared-library-subpath,egl)
+
+LOCAL_SRC_FILES += glesv1_emul_ifc.cpp
+
+$(call emugl-end-module)
+
+emulatorOpengl := $(LOCAL_PATH)/../..
+logTag := -DLOG_TAG=\"eglWrapper\"
+EMUGEN = $(BUILD_OUT_EXECUTABLES)/emugen
+## comment for no debug
+#debugFlags = -g -O0
+
+#### libGLESv2_CM_emul.so
+$(call emugl-begin-shared-library, libGLESv2_emul)
+$(call emugl-import,libGLESv2_enc)
+$(call emugl-gen-wrapper,$(EMUGL_PATH)/system/GLESv2_enc,gl2)
+LOCAL_SRC_FILES += glesv2_emul_ifc.cpp
+$(call emugl-set-shared-library-subpath,egl)
+$(call emugl-end-module)
+
+##### libEGL_emul.so ###########
+
+# THE FOLLOWING DOESN'T WORK YET
+#
+$(call emugl-begin-shared-library,libEGL_emul)
+$(call emugl-import,libut_rendercontrol_enc libGLESv1_CM_emul libGLESv2_emul libOpenglSystemCommon)
+
+$(call emugl-set-shared-library-subpath,egl)
+LOCAL_CFLAGS += $(logTag)
+
+LOCAL_SRC_FILES :=  \
+        egl.cpp \
+        egl_dispatch.cpp \
+        ServerConnection.cpp \
+        ThreadInfo.cpp
+
+$(call emugl-end-module)
+
+#### egl.cfg ####
+
+# Ensure that this file is only copied to emulator-specific builds.
+# Other builds are device-specific and will provide their own
+# version of this file to point to the appropriate HW EGL libraries.
+#
+ifneq (,$(filter full full_x86 full_mips sdk sdk_x86 sdk_mips,$(TARGET_PRODUCT)))
+ifeq (,$(BUILD_EMULATOR_OPENGL_DRIVER))
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := egl.cfg
+LOCAL_SRC_FILES := $(LOCAL_MODULE)
+
+LOCAL_MODULE_PATH := $(TARGET_OUT)/lib/egl
+LOCAL_MODULE_CLASS := ETC
+
+include $(BUILD_PREBUILT)
+endif # building 'real' driver BUILD_EMULATOR_OPENGL_DRIVER
+endif # TARGET_PRODUCT in 'full sdk full_x86 sdk_x86 full_mips sdk_mips'
+
+#### gles_emul.cfg ####
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := gles_emul.cfg
+LOCAL_SRC_FILES := $(LOCAL_MODULE)
+
+LOCAL_MODULE_PATH := $(TARGET_OUT)/etc
+LOCAL_MODULE_CLASS := ETC
+
+include $(BUILD_PREBUILT)
diff --git a/opengl/tests/gles_android_wrapper/ApiInitializer.h b/opengl/tests/gles_android_wrapper/ApiInitializer.h
new file mode 100644
index 0000000..793c735
--- /dev/null
+++ b/opengl/tests/gles_android_wrapper/ApiInitializer.h
@@ -0,0 +1,42 @@
+/*
+* Copyright 2011 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.
+*/
+
+#ifndef _API_INITIALIZER_H_
+#define _API_INITIALIZER_H_
+#include <stdlib.h>
+#include <dlfcn.h>
+
+class ApiInitializer {
+public:
+    ApiInitializer(void *dso) :
+        m_dso(dso) {
+    }
+    static void *s_getProc(const char *name, void *userData) {
+        ApiInitializer *self = (ApiInitializer *)userData;
+        return self->getProc(name);
+    }
+private:
+    void *m_dso;
+    void *getProc(const char *name) {
+        void *symbol = NULL;
+        if (m_dso) {
+            symbol = dlsym(m_dso, name);
+        }
+        return symbol;
+    }
+};
+
+#endif
diff --git a/opengl/tests/gles_android_wrapper/CleanSpec.mk b/opengl/tests/gles_android_wrapper/CleanSpec.mk
new file mode 100644
index 0000000..f56383a
--- /dev/null
+++ b/opengl/tests/gles_android_wrapper/CleanSpec.mk
@@ -0,0 +1,50 @@
+# Copyright (C) 2007 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.
+#
+
+# If you don't need to do a full clean build but would like to touch
+# a file or delete some intermediate files, add a clean step to the end
+# of the list.  These steps will only be run once, if they haven't been
+# run before.
+#
+# E.g.:
+#     $(call add-clean-step, touch -c external/sqlite/sqlite3.h)
+#     $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)
+#
+# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with
+# files that are missing or have been moved.
+#
+# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory.
+# Use $(OUT_DIR) to refer to the "out" directory.
+#
+# If you need to re-do something that's already mentioned, just copy
+# the command and add it to the bottom of the list.  E.g., if a change
+# that you made last week required touching a file and a change you
+# made today requires touching the same file, just copy the old
+# touch step and add it to the end of the list.
+#
+# ************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
+# ************************************************
+
+# For example:
+#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates)
+#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)
+#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
+#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
+
+# ************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
+# ************************************************
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/SHARED_LIBRARIES/libGLES_emul_intermediates)
diff --git a/opengl/tests/gles_android_wrapper/ServerConnection.cpp b/opengl/tests/gles_android_wrapper/ServerConnection.cpp
new file mode 100644
index 0000000..ff4e390
--- /dev/null
+++ b/opengl/tests/gles_android_wrapper/ServerConnection.cpp
@@ -0,0 +1,125 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include "ServerConnection.h"
+#include "TcpStream.h"
+#include "QemuPipeStream.h"
+#include <cutils/log.h>
+#include "ThreadInfo.h"
+
+gl_client_context_t *ServerConnection::s_getGlContext()
+{
+    EGLThreadInfo *ti = getEGLThreadInfo();
+    if (ti->serverConn) {
+        return ti->serverConn->m_glEnc;
+    }
+    return NULL;
+}
+
+gl2_client_context_t *ServerConnection::s_getGl2Context()
+{
+    EGLThreadInfo *ti = getEGLThreadInfo();
+    if (ti->serverConn) {
+        return ti->serverConn->m_gl2Enc;
+    }
+    return NULL;
+}
+
+ServerConnection *ServerConnection::s_getServerConnection()
+{
+    EGLThreadInfo *ti = getEGLThreadInfo();
+    if (!ti->serverConn)
+    {
+        ti->serverConn = new ServerConnection();
+        if (ti->serverConn->create() < 0) {
+            delete ti->serverConn;
+            ti->serverConn = NULL;
+        }
+    }
+
+    return ti->serverConn;
+}
+
+
+ServerConnection::ServerConnection() :
+    m_stream(NULL),
+    m_glEnc(NULL),
+    m_ut_enc(NULL)
+{
+}
+
+ServerConnection::~ServerConnection()
+{
+    delete m_ut_enc;
+    delete m_glEnc;
+    delete m_stream;
+}
+
+
+
+int ServerConnection::create(size_t bufsize,
+                             const char *defaultServer)
+{
+    /* XXX: Make configurable through system property */
+    int useQemuPipe = 1;
+
+    if (m_stream != NULL) delete(m_stream);
+
+    if (useQemuPipe) {
+        QemuPipeStream*  pipeStream = new QemuPipeStream(bufsize);
+
+        if (pipeStream->connect() < 0) {
+            ALOGE("couldn't connect to host server\n");
+            delete pipeStream;
+            return -1;
+        }
+        m_stream = pipeStream;
+    }
+    else /* !useQemuPipe */
+    {
+        TcpStream*  tcpStream = new TcpStream(bufsize);
+
+        char *s = getenv(ENV_RGL_SERVER);
+        char *hostname;
+        if (s == NULL) {
+            hostname = strdup(defaultServer);
+        } else {
+            hostname = strdup(s);
+        }
+
+        if (tcpStream->connect(hostname, CODEC_SERVER_PORT) < 0) {
+            ALOGE("couldn't connect to %s\n", hostname);
+            free(hostname);
+            delete tcpStream;
+            return -1;
+        }
+        LOGI("connecting to server %s\n", hostname);
+        free(hostname);
+
+        m_stream = tcpStream;
+    }
+
+    m_glEnc = new GLEncoder(m_stream);
+    m_glEnc->setContextAccessor(s_getGlContext);
+
+    m_gl2Enc = new GL2Encoder(m_stream);
+    m_gl2Enc->setContextAccessor(s_getGl2Context);
+
+    m_ut_enc = new ut_rendercontrol_encoder_context_t(m_stream);
+    return 0;
+}
+
diff --git a/opengl/tests/gles_android_wrapper/ServerConnection.h b/opengl/tests/gles_android_wrapper/ServerConnection.h
new file mode 100644
index 0000000..84f40d8
--- /dev/null
+++ b/opengl/tests/gles_android_wrapper/ServerConnection.h
@@ -0,0 +1,55 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#ifndef _SERVER_CONNECTION_H
+#define _SERVER_CONNECTION_H
+
+#include "GLEncoder.h"
+#include "GL2Encoder.h"
+#include "IOStream.h"
+#include "codec_defs.h"
+#include "ut_rendercontrol_enc.h"
+#include <pthread.h>
+
+#define ENV_RGL_SERVER "RGL_SERVER"
+#define RGL_DEFAULT_SERVER "10.0.2.2"
+
+class ServerConnection {
+public:
+    ~ServerConnection();
+    int create(size_t buf_size = 4 * 1024 * 1024, const char *defaultServer = RGL_DEFAULT_SERVER);
+    static gl_client_context_t *s_getGlContext();
+    static ServerConnection *s_getServerConnection();
+    static gl2_client_context_t *s_getGl2Context();
+    GLEncoder *glEncoder() { return m_glEnc; }
+    GL2Encoder *gl2Encoder() { return m_gl2Enc; }
+    ut_rendercontrol_encoder_context_t * utEnc() { return m_ut_enc; }
+
+private:
+    ServerConnection();
+
+private:
+    static pthread_key_t s_glKey;
+    static pthread_key_t s_connectionKey;
+    static void s_initKeys();
+    IOStream *m_stream;
+    GLEncoder *m_glEnc;
+    GL2Encoder *m_gl2Enc;
+    ut_rendercontrol_encoder_context_t *m_ut_enc;
+
+};
+
+
+#endif
diff --git a/opengl/tests/gles_android_wrapper/ThreadInfo.cpp b/opengl/tests/gles_android_wrapper/ThreadInfo.cpp
new file mode 100644
index 0000000..5bf6a7d
--- /dev/null
+++ b/opengl/tests/gles_android_wrapper/ThreadInfo.cpp
@@ -0,0 +1,39 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#include "ThreadInfo.h"
+#include "cutils/threads.h"
+
+thread_store_t s_tls = THREAD_STORE_INITIALIZER;
+
+static void tlsDestruct(void *ptr)
+{
+    if (ptr) {
+        EGLThreadInfo *ti = (EGLThreadInfo *)ptr;
+        delete ti->serverConn;
+        delete ti;
+    }
+}
+
+EGLThreadInfo *getEGLThreadInfo()
+{
+    EGLThreadInfo *ti = (EGLThreadInfo *)thread_store_get(&s_tls);
+    if (ti) return ti;
+
+    ti = new EGLThreadInfo();
+    thread_store_set(&s_tls, ti, tlsDestruct);
+
+    return ti;
+}
diff --git a/opengl/tests/gles_android_wrapper/ThreadInfo.h b/opengl/tests/gles_android_wrapper/ThreadInfo.h
new file mode 100644
index 0000000..f748a39
--- /dev/null
+++ b/opengl/tests/gles_android_wrapper/ThreadInfo.h
@@ -0,0 +1,49 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#ifndef _THREAD_INFO_H
+#define _THREAD_INFO_H
+
+#include "ServerConnection.h"
+#include <EGL/egl.h>
+
+struct EGLWrapperContext
+{
+    EGLWrapperContext(EGLContext p_aglContext, int _version) {
+        aglContext = p_aglContext;
+        clientState = NULL;
+        version = _version;
+    }
+
+    ~EGLWrapperContext() {
+        delete clientState;
+    }
+
+    EGLContext aglContext;
+    GLClientState *clientState;
+    int version;
+};
+
+struct EGLThreadInfo
+{
+    EGLThreadInfo() : currentContext(NULL), serverConn(NULL) {}
+
+    EGLWrapperContext *currentContext;
+    ServerConnection *serverConn;
+};
+
+
+EGLThreadInfo *getEGLThreadInfo();
+#endif
diff --git a/opengl/tests/gles_android_wrapper/egl.cfg b/opengl/tests/gles_android_wrapper/egl.cfg
new file mode 100644
index 0000000..891b07d
--- /dev/null
+++ b/opengl/tests/gles_android_wrapper/egl.cfg
@@ -0,0 +1 @@
+0 0 emul
\ No newline at end of file
diff --git a/opengl/tests/gles_android_wrapper/egl.cpp b/opengl/tests/gles_android_wrapper/egl.cpp
new file mode 100644
index 0000000..1e2e456
--- /dev/null
+++ b/opengl/tests/gles_android_wrapper/egl.cpp
@@ -0,0 +1,663 @@
+/*
+* Copyright (C) 2011 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.
+*/
+
+//
+// WARNING -------------------------- WARNING
+// This code meant to be used for testing purposes only. It is not production
+// level quality.
+// Use on your own risk !!
+//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dlfcn.h>
+#include "egl_dispatch.h"
+#include "egl_ftable.h"
+#include <cutils/process_name.h>
+#include <cutils/log.h>
+#include "ServerConnection.h"
+#include "ThreadInfo.h"
+#include <pthread.h>
+#include "gl_wrapper_context.h"
+#include "gl2_wrapper_context.h"
+
+#define GLES_EMUL_TARGETS_FILE "/system/etc/gles_emul.cfg"
+// implementation libraries;
+#define GLESv1_enc_LIB "/system/lib/libGLESv1_enc.so"
+#define GLESv2_enc_LIB "/system/lib/libGLESv2_enc.so"
+#define GLES_android_LIB "/system/lib/egl/libGLES_android.so"
+// driver libraries;
+#define GLESv1_DRIVER "/system/lib/egl/libGLESv1_CM_emul.so"
+#define GLESv2_DRIVER "/system/lib/egl/libGLESv2_emul.so"
+
+
+static struct egl_dispatch *s_dispatch = NULL;
+pthread_once_t dispatchTablesInitialized = PTHREAD_ONCE_INIT;
+
+static bool s_needEncode = false;
+
+static gl_wrapper_context_t *g_gl_dispatch = NULL;
+static gl2_wrapper_context_t *g_gl2_dispatch = NULL;
+
+template <class T>
+int initApi(const char *driverLibName, const char *implLibName, T **dispatchTable, T *(*accessor)())
+{
+    void *driverLib = dlopen(driverLibName, RTLD_NOW | RTLD_LOCAL);
+    if (driverLib == NULL) {
+        ALOGE("failed to load %s : %s\n", driverLibName, dlerror());
+        return -1;
+    }
+
+    typedef T *(*createFcn_t)(void *, T *(*accessor)());
+    createFcn_t createFcn;
+    createFcn = (createFcn_t) dlsym(driverLib, "createFromLib");
+    if (createFcn == NULL) {
+        ALOGE("failed to load createFromLib constructor function\n");
+        return -1;
+    }
+
+    void *implLib = dlopen(implLibName, RTLD_NOW | RTLD_LOCAL);
+    if (implLib == NULL) {
+        ALOGE("couldn't open %s", implLibName);
+        return -2;
+    }
+    *dispatchTable = createFcn(implLib, accessor);
+    if (*dispatchTable == NULL) {
+        return -3;
+    }
+
+    // XXX - we do close the impl library since it doesn't have data, as far as we concern.
+    dlclose(implLib);
+
+    // XXX - we do not dlclose the driver library, so its not initialized when
+    // later loaded by android - is this required?
+    ALOGD("loading %s into %s complete\n", implLibName, driverLibName);
+    return 0;
+
+}
+
+static gl_wrapper_context_t *getGLContext()
+{
+    return g_gl_dispatch;
+}
+
+static gl2_wrapper_context_t *getGL2Context()
+{
+    return g_gl2_dispatch;
+}
+
+const char *getProcName()
+{
+    static const char *procname = NULL;
+
+    if (procname == NULL) {
+        const char *str = get_process_name();
+        if (strcmp(str, "unknown") != 0) {
+            procname = str;
+        } else {
+            // we need to obtain our process name from the command line;
+            FILE *fp = fopen("/proc/self/cmdline", "rt");
+            if (fp == NULL) {
+                ALOGE("couldn't open /proc/self/cmdline\n");
+                return NULL;
+            }
+
+            char line[1000];
+            if (fgets(line, sizeof(line), fp) == NULL) {
+                ALOGE("couldn't read the self cmdline from \n");
+                fclose(fp);
+                return NULL;
+            }
+            fclose(fp);
+
+            if (line[0] == '\0') {
+                ALOGE("cmdline is empty\n");
+                return NULL;
+            }
+
+            //obtain the basename;
+            line[sizeof(line) - 1] = '\0';
+            char *p = line;
+            while (*p != '\0' &&
+                   *p != '\t' &&
+                   *p != ' ' &&
+                   *p != '\n') {
+                p++;
+            }
+
+            *p = '\0'; p--;
+            while (p > line && *p != '/') p--;
+            if (*p == '/') p++;
+            procname = strdup(p);
+        }
+    }
+
+    return procname;
+}
+
+
+
+bool isNeedEncode()
+{
+    const char *procname = getProcName();
+    if (procname == NULL) return false;
+    ALOGD("isNeedEncode? for %s\n", procname);
+    // check on our whitelist
+    FILE *fp = fopen(GLES_EMUL_TARGETS_FILE, "rt");
+    if (fp == NULL) {
+        ALOGE("couldn't open %s\n", GLES_EMUL_TARGETS_FILE);
+        return false;
+    }
+
+    char line[100];
+    bool found = false;
+    size_t  procnameLen = strlen(procname);
+
+    while (fgets(line, sizeof(line), fp) != NULL) {
+        if (strlen(line) >= procnameLen &&
+            !strncmp(procname, line, procnameLen)) {
+            char c = line[procnameLen];
+            if (c == '\0' || c == ' ' || c == '\t' || c == '\n') {
+                found = true;
+                ALOGD("should use encoder for %s\n", procname);
+                break;
+            }
+        }
+    }
+    fclose(fp);
+    return found;
+}
+
+void initDispatchTables()
+{
+    //
+    // Load our back-end implementation of EGL/GLES
+    //
+    ALOGD("Loading egl dispatch for %s\n", getProcName());
+
+    void *gles_android = dlopen("/system/lib/egl/libGLES_android.so", RTLD_NOW | RTLD_LOCAL);
+    if (!gles_android) {
+        fprintf(stderr,"FATAL ERROR: Could not load libGLES_android lib\n");
+        exit(-1);
+    }
+
+    //
+    // Load back-end EGL implementation library
+    //
+    s_dispatch = create_egl_dispatch( gles_android );
+    if (!s_dispatch) {
+        fprintf(stderr,"FATAL ERROR: Could not create egl dispatch\n");
+        exit(-1);
+    }
+
+    //
+    // initialize gles
+    //
+    s_needEncode = isNeedEncode();
+    void *gles_encoder = NULL;
+    if (s_needEncode) {
+        // initialize a connection to the server, and the GLESv1/v2 encoders;
+        ServerConnection * connection = ServerConnection::s_getServerConnection();
+        if (connection == NULL) {
+            ALOGE("couldn't create server connection\n");
+            s_needEncode = false;
+        }
+    }
+
+    // init dispatch tabels for GLESv1 & GLESv2
+    if (s_needEncode) {
+        // XXX - we do not check the retrun value because there isn't much we can do here on failure.
+
+        if (initApi<gl_wrapper_context_t>(GLESv1_DRIVER, GLESv1_enc_LIB, &g_gl_dispatch, getGLContext) < 0) {
+            // fallback to android on faluire
+            s_needEncode = false;
+        } else {
+            initApi<gl2_wrapper_context_t>(GLESv2_DRIVER, GLESv2_enc_LIB, &g_gl2_dispatch, getGL2Context);
+        }
+    }
+
+    if (!s_needEncode) {
+        ALOGD("Initializing native opengl for %s\n", getProcName());
+        initApi<gl_wrapper_context_t>(GLESv1_DRIVER, GLES_android_LIB, &g_gl_dispatch, getGLContext);
+        // try to initialize gl2 from GLES, though its probably going to fail
+        initApi<gl2_wrapper_context_t>(GLESv2_DRIVER, GLES_android_LIB, &g_gl2_dispatch, getGL2Context);
+    }
+}
+
+static struct egl_dispatch *getDispatch()
+{
+    pthread_once(&dispatchTablesInitialized, initDispatchTables);
+    return s_dispatch;
+}
+
+__eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname)
+{
+
+    // search in EGL function table
+    for (int i=0; i<egl_num_funcs; i++) {
+        if (!strcmp(egl_funcs_by_name[i].name, procname)) {
+            return (__eglMustCastToProperFunctionPointerType)egl_funcs_by_name[i].proc;
+        }
+    }
+
+    // we do not support eglGetProcAddress for GLESv1 & GLESv2. The loader
+    // should be able to find this function through dynamic loading.
+    return NULL;
+}
+
+////////////////  Path through functions //////////
+
+EGLint eglGetError()
+{
+    return getDispatch()->eglGetError();
+}
+
+EGLDisplay eglGetDisplay(EGLNativeDisplayType display_id)
+{
+    return getDispatch()->eglGetDisplay(display_id);
+}
+
+EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
+{
+    return getDispatch()->eglInitialize(dpy, major, minor);
+}
+
+EGLBoolean eglTerminate(EGLDisplay dpy)
+{
+    return getDispatch()->eglTerminate(dpy);
+}
+
+const char* eglQueryString(EGLDisplay dpy, EGLint name)
+{
+    return getDispatch()->eglQueryString(dpy, name);
+}
+
+EGLBoolean eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
+{
+    return getDispatch()->eglGetConfigs(dpy, configs, config_size, num_config);
+}
+
+static EGLint * filter_es2_bit(const EGLint *attrib_list, bool *isES2)
+{
+    if (attrib_list == NULL) {
+        if (isES2 != NULL) *isES2 = false;
+        return NULL;
+    }
+
+    EGLint *attribs = NULL;
+    int nAttribs = 0;
+    while(attrib_list[nAttribs] != EGL_NONE) nAttribs++;
+    nAttribs++;
+
+    attribs = new EGLint[nAttribs];
+    memcpy(attribs, attrib_list, nAttribs * sizeof(EGLint));
+    if (isES2 != NULL) *isES2 = false;
+
+    // scan the attribute list for ES2 request and replace with ES1.
+    for (int i = 0; i < nAttribs; i++) {
+        if (attribs[i] == EGL_RENDERABLE_TYPE) {
+            if (attribs[i + 1] & EGL_OPENGL_ES2_BIT) {
+                attribs[i + 1] &= ~EGL_OPENGL_ES2_BIT;
+                attribs[i + 1] |= EGL_OPENGL_ES_BIT;
+                ALOGD("removing ES2 bit 0x%x\n", attribs[i + 1]);
+                if (isES2 != NULL) *isES2 = true;
+            }
+        }
+    }
+    return attribs;
+}
+
+EGLBoolean eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
+{
+    EGLBoolean res;
+    if (s_needEncode) {
+        EGLint *attribs = filter_es2_bit(attrib_list, NULL);
+        res =  getDispatch()->eglChooseConfig(dpy,
+                                              attribs,
+                                              configs,
+                                              config_size,
+                                              num_config);
+        ALOGD("eglChooseConfig: %d configs found\n", *num_config);
+        if (*num_config == 0 && attribs != NULL) {
+            ALOGD("requested attributes:\n");
+            for (int i = 0; attribs[i] != EGL_NONE; i++) {
+                ALOGD("%d: 0x%x\n", i, attribs[i]);
+            }
+        }
+
+        delete attribs;
+    } else {
+        res = getDispatch()->eglChooseConfig(dpy, attrib_list, configs, config_size, num_config);
+    }
+    return res;
+}
+
+EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
+{
+    if (s_needEncode && attribute == EGL_RENDERABLE_TYPE) {
+        *value = EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT;
+        return EGL_TRUE;
+    } else {
+        return getDispatch()->eglGetConfigAttrib(dpy, config, attribute, value);
+    }
+}
+
+EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list)
+{
+    EGLSurface surface =  getDispatch()->eglCreateWindowSurface(dpy, config, win, attrib_list);
+    if (surface != EGL_NO_SURFACE) {
+        ServerConnection *server;
+        if (s_needEncode && (server = ServerConnection::s_getServerConnection()) != NULL) {
+            server->utEnc()->createSurface(server->utEnc(), getpid(), (uint32_t)surface);
+        }
+    }
+    return surface;
+}
+
+EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
+{
+    EGLSurface surface =  getDispatch()->eglCreatePbufferSurface(dpy, config, attrib_list);
+    if (surface != EGL_NO_SURFACE) {
+        ServerConnection *server;
+        if (s_needEncode && (server = ServerConnection::s_getServerConnection()) != NULL) {
+            server->utEnc()->createSurface(server->utEnc(), getpid(), (uint32_t)surface);
+        }
+    }
+    return surface;
+}
+
+EGLSurface eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
+{
+    EGLSurface surface =  getDispatch()->eglCreatePixmapSurface(dpy, config, pixmap, attrib_list);
+    if (surface != EGL_NO_SURFACE) {
+        ServerConnection *server;
+        if (s_needEncode && (server = ServerConnection::s_getServerConnection()) != NULL) {
+            server->utEnc()->createSurface(server->utEnc(), getpid(), (uint32_t)surface);
+        }
+    }
+    return surface;
+}
+
+EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
+{
+    EGLBoolean res =  getDispatch()->eglDestroySurface(dpy, surface);
+    if (res && surface != EGL_NO_SURFACE) {
+        ServerConnection *server;
+        if (s_needEncode && (server = ServerConnection::s_getServerConnection()) != NULL) {
+            server->utEnc()->destroySurface(server->utEnc(), getpid(), (uint32_t)surface);
+        }
+    }
+    return res;
+}
+
+EGLBoolean eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
+{
+    EGLBoolean res = getDispatch()->eglQuerySurface(dpy, surface, attribute, value);
+    if (res && attribute == EGL_RENDERABLE_TYPE) {
+        *value |= EGL_OPENGL_ES2_BIT;
+    }
+    return res;
+}
+
+EGLBoolean eglBindAPI(EGLenum api)
+{
+    return getDispatch()->eglBindAPI(api);
+}
+
+EGLenum eglQueryAPI()
+{
+    return getDispatch()->eglQueryAPI();
+}
+
+EGLBoolean eglWaitClient()
+{
+    return getDispatch()->eglWaitClient();
+}
+
+EGLBoolean eglReleaseThread()
+{
+    return getDispatch()->eglReleaseThread();
+}
+
+EGLSurface eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)
+{
+    return getDispatch()->eglCreatePbufferFromClientBuffer(dpy, buftype, buffer, config, attrib_list);
+}
+
+EGLBoolean eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
+{
+    return getDispatch()->eglSurfaceAttrib(dpy, surface, attribute, value);
+}
+
+EGLBoolean eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+    return getDispatch()->eglBindTexImage(dpy, surface, buffer);
+}
+
+EGLBoolean eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+    return getDispatch()->eglReleaseTexImage(dpy, surface, buffer);
+}
+
+EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval)
+{
+    return getDispatch()->eglSwapInterval(dpy, interval);
+}
+
+EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
+{
+
+    EGLContext share = share_context;
+    if (share) share = ((EGLWrapperContext *)share_context)->aglContext;
+
+    // check if are ES2, and convert it to ES1.
+    int nAttribs = 0;
+    if (attrib_list != NULL) {
+        while(attrib_list[nAttribs] != EGL_NONE) {
+            nAttribs++;
+        }
+        nAttribs++;
+    }
+
+    EGLint *attrib = NULL;
+    if (nAttribs > 0) {
+        attrib = new EGLint[nAttribs];
+        memcpy(attrib, attrib_list, nAttribs * sizeof(EGLint));
+    }
+
+    int  version  = 1;
+    for (int i = 0; i < nAttribs; i++) {
+        if (attrib[i] == EGL_CONTEXT_CLIENT_VERSION &&
+            attrib[i + 1] == 2) {
+            version = 2;
+            attrib[i + 1] = 1; // replace to version 1
+        }
+    }
+
+    EGLContext ctx =  getDispatch()->eglCreateContext(dpy, config, share, attrib);
+    delete attrib;
+    EGLWrapperContext *wctx = new EGLWrapperContext(ctx, version);
+    if (ctx != EGL_NO_CONTEXT) {
+        ServerConnection *server;
+        if (s_needEncode && (server = ServerConnection::s_getServerConnection()) != NULL) {
+            wctx->clientState = new GLClientState();
+            server->utEnc()->createContext(server->utEnc(), getpid(),
+                                           (uint32_t)wctx,
+                                           (uint32_t)(share_context == EGL_NO_CONTEXT ? 0 : share_context), wctx->version);
+        }
+    }
+    return (EGLContext)wctx;
+}
+
+EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
+{
+    EGLWrapperContext *wctx = (EGLWrapperContext *)ctx;
+    EGLBoolean res = EGL_FALSE;
+
+    if (ctx && ctx != EGL_NO_CONTEXT) {
+        res = getDispatch()->eglDestroyContext(dpy, wctx->aglContext);
+        if (res) {
+            EGLThreadInfo *ti = getEGLThreadInfo();
+            ServerConnection *server;
+            if (s_needEncode && (server = ServerConnection::s_getServerConnection())) {
+                server->utEnc()->destroyContext(ti->serverConn->utEnc(), getpid(), (uint32_t)ctx);
+            }
+            if (ti->currentContext == wctx) ti->currentContext = NULL;
+            delete wctx;
+        }
+    }
+
+    return res;
+}
+
+EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
+{
+    EGLWrapperContext *wctx = (EGLWrapperContext *)ctx;
+    EGLContext aglContext = (ctx == EGL_NO_CONTEXT ? EGL_NO_CONTEXT : wctx->aglContext);
+    EGLThreadInfo *ti = getEGLThreadInfo();
+    EGLBoolean res = getDispatch()->eglMakeCurrent(dpy, draw, read, aglContext);
+    if (res ) {
+        // NOTE - we do get a pointer to the server connection, (rather then using ti->serverConn)
+        // for cases that this is the first egl call of the current thread.
+
+        ServerConnection *server;
+        if (s_needEncode && (server = ServerConnection::s_getServerConnection())) {
+            server->utEnc()->makeCurrentContext(server->utEnc(), getpid(),
+                                                (uint32_t) (draw == EGL_NO_SURFACE ? 0 : draw),
+                                                (uint32_t) (read == EGL_NO_SURFACE ? 0 : read),
+                                                (uint32_t) (ctx == EGL_NO_CONTEXT ? 0 : ctx));
+            server->glEncoder()->setClientState( wctx ? wctx->clientState : NULL );
+            server->gl2Encoder()->setClientState( wctx ? wctx->clientState : NULL );
+        }
+
+        // set current context in our thread info
+        ti->currentContext = wctx;
+    }
+    return res;
+
+}
+
+EGLContext eglGetCurrentContext()
+{
+    EGLThreadInfo *ti = getEGLThreadInfo();
+    return (ti->currentContext ? ti->currentContext : EGL_NO_CONTEXT);
+}
+
+EGLSurface eglGetCurrentSurface(EGLint readdraw)
+{
+    return getDispatch()->eglGetCurrentSurface(readdraw);
+}
+
+EGLDisplay eglGetCurrentDisplay()
+{
+    return getDispatch()->eglGetCurrentDisplay();
+}
+
+EGLBoolean eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
+{
+    EGLWrapperContext *wctx = (EGLWrapperContext *)ctx;
+    if (wctx) {
+        if (attribute == EGL_CONTEXT_CLIENT_VERSION) {
+            *value = wctx->version;
+            return EGL_TRUE;
+        } else {
+            return getDispatch()->eglQueryContext(dpy, wctx->aglContext, attribute, value);
+        }
+    }
+    else {
+        return EGL_BAD_CONTEXT;
+    }
+}
+
+EGLBoolean eglWaitGL()
+{
+    return getDispatch()->eglWaitGL();
+}
+
+EGLBoolean eglWaitNative(EGLint engine)
+{
+    return getDispatch()->eglWaitNative(engine);
+}
+
+EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
+{
+    ServerConnection *server;
+    if (s_needEncode && (server = ServerConnection::s_getServerConnection()) != NULL) {
+        server->utEnc()->swapBuffers(server->utEnc(), getpid(), (uint32_t)surface);
+        server->glEncoder()->flush();
+        server->gl2Encoder()->flush();
+        return 1;
+    }
+    return getDispatch()->eglSwapBuffers(dpy, surface);
+}
+
+EGLBoolean eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
+{
+    return getDispatch()->eglCopyBuffers(dpy, surface, target);
+}
+
+EGLBoolean eglLockSurfaceKHR(EGLDisplay display, EGLSurface surface, const EGLint *attrib_list)
+{
+    return getDispatch()->eglLockSurfaceKHR(display, surface, attrib_list);
+}
+
+EGLBoolean eglUnlockSurfaceKHR(EGLDisplay display, EGLSurface surface)
+{
+    return getDispatch()->eglUnlockSurfaceKHR(display, surface);
+}
+
+EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)
+{
+    EGLWrapperContext *wctx = (EGLWrapperContext *)ctx;
+    EGLContext aglContext = (wctx ? wctx->aglContext : EGL_NO_CONTEXT);
+    return getDispatch()->eglCreateImageKHR(dpy, aglContext, target, buffer, attrib_list);
+}
+
+EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
+{
+    return getDispatch()->eglDestroyImageKHR(dpy, image);
+}
+
+EGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
+{
+    return getDispatch()->eglCreateSyncKHR(dpy, type, attrib_list);
+}
+
+EGLBoolean eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
+{
+    return getDispatch()->eglDestroySyncKHR(dpy, sync);
+}
+
+EGLint eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)
+{
+    return getDispatch()->eglClientWaitSyncKHR(dpy, sync, flags, timeout);
+}
+
+EGLBoolean eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode)
+{
+    return getDispatch()->eglSignalSyncKHR(dpy, sync, mode);
+}
+
+EGLBoolean eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)
+{
+    return getDispatch()->eglGetSyncAttribKHR(dpy, sync, attribute, value);
+}
+
+EGLBoolean eglSetSwapRectangleANDROID(EGLDisplay dpy, EGLSurface draw, EGLint left, EGLint top, EGLint width, EGLint height)
+{
+    return getDispatch()->eglSetSwapRectangleANDROID(dpy, draw, left, top, width, height);
+}
diff --git a/opengl/tests/gles_android_wrapper/egl_dispatch.cpp b/opengl/tests/gles_android_wrapper/egl_dispatch.cpp
new file mode 100644
index 0000000..f69ca61
--- /dev/null
+++ b/opengl/tests/gles_android_wrapper/egl_dispatch.cpp
@@ -0,0 +1,71 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#include <stdio.h>
+#include "egl_dispatch.h"
+#include <dlfcn.h>
+
+egl_dispatch *create_egl_dispatch(void *gles_android)
+{
+        egl_dispatch *disp = new egl_dispatch;
+
+    void *ptr;
+    ptr = dlsym(gles_android,"eglGetError"); disp->set_eglGetError((eglGetError_t)ptr);
+    ptr = dlsym(gles_android,"eglGetDisplay"); disp->set_eglGetDisplay((eglGetDisplay_t)ptr);
+    ptr = dlsym(gles_android,"eglInitialize"); disp->set_eglInitialize((eglInitialize_t)ptr);
+    ptr = dlsym(gles_android,"eglTerminate"); disp->set_eglTerminate((eglTerminate_t)ptr);
+    ptr = dlsym(gles_android,"eglQueryString"); disp->set_eglQueryString((eglQueryString_t)ptr);
+    ptr = dlsym(gles_android,"eglGetConfigs"); disp->set_eglGetConfigs((eglGetConfigs_t)ptr);
+    ptr = dlsym(gles_android,"eglChooseConfig"); disp->set_eglChooseConfig((eglChooseConfig_t)ptr);
+    ptr = dlsym(gles_android,"eglGetConfigAttrib"); disp->set_eglGetConfigAttrib((eglGetConfigAttrib_t)ptr);
+    ptr = dlsym(gles_android,"eglCreateWindowSurface"); disp->set_eglCreateWindowSurface((eglCreateWindowSurface_t)ptr);
+    ptr = dlsym(gles_android,"eglCreatePbufferSurface"); disp->set_eglCreatePbufferSurface((eglCreatePbufferSurface_t)ptr);
+    ptr = dlsym(gles_android,"eglCreatePixmapSurface"); disp->set_eglCreatePixmapSurface((eglCreatePixmapSurface_t)ptr);
+    ptr = dlsym(gles_android,"eglDestroySurface"); disp->set_eglDestroySurface((eglDestroySurface_t)ptr);
+    ptr = dlsym(gles_android,"eglQuerySurface"); disp->set_eglQuerySurface((eglQuerySurface_t)ptr);
+    ptr = dlsym(gles_android,"eglBindAPI"); disp->set_eglBindAPI((eglBindAPI_t)ptr);
+    ptr = dlsym(gles_android,"eglQueryAPI"); disp->set_eglQueryAPI((eglQueryAPI_t)ptr);
+    ptr = dlsym(gles_android,"eglWaitClient"); disp->set_eglWaitClient((eglWaitClient_t)ptr);
+    ptr = dlsym(gles_android,"eglReleaseThread"); disp->set_eglReleaseThread((eglReleaseThread_t)ptr);
+    ptr = dlsym(gles_android,"eglCreatePbufferFromClientBuffer"); disp->set_eglCreatePbufferFromClientBuffer((eglCreatePbufferFromClientBuffer_t)ptr);
+    ptr = dlsym(gles_android,"eglSurfaceAttrib"); disp->set_eglSurfaceAttrib((eglSurfaceAttrib_t)ptr);
+    ptr = dlsym(gles_android,"eglBindTexImage"); disp->set_eglBindTexImage((eglBindTexImage_t)ptr);
+    ptr = dlsym(gles_android,"eglReleaseTexImage"); disp->set_eglReleaseTexImage((eglReleaseTexImage_t)ptr);
+    ptr = dlsym(gles_android,"eglSwapInterval"); disp->set_eglSwapInterval((eglSwapInterval_t)ptr);
+    ptr = dlsym(gles_android,"eglCreateContext"); disp->set_eglCreateContext((eglCreateContext_t)ptr);
+    ptr = dlsym(gles_android,"eglDestroyContext"); disp->set_eglDestroyContext((eglDestroyContext_t)ptr);
+    ptr = dlsym(gles_android,"eglMakeCurrent"); disp->set_eglMakeCurrent((eglMakeCurrent_t)ptr);
+    ptr = dlsym(gles_android,"eglGetCurrentContext"); disp->set_eglGetCurrentContext((eglGetCurrentContext_t)ptr);
+    ptr = dlsym(gles_android,"eglGetCurrentSurface"); disp->set_eglGetCurrentSurface((eglGetCurrentSurface_t)ptr);
+    ptr = dlsym(gles_android,"eglGetCurrentDisplay"); disp->set_eglGetCurrentDisplay((eglGetCurrentDisplay_t)ptr);
+    ptr = dlsym(gles_android,"eglQueryContext"); disp->set_eglQueryContext((eglQueryContext_t)ptr);
+    ptr = dlsym(gles_android,"eglWaitGL"); disp->set_eglWaitGL((eglWaitGL_t)ptr);
+    ptr = dlsym(gles_android,"eglWaitNative"); disp->set_eglWaitNative((eglWaitNative_t)ptr);
+    ptr = dlsym(gles_android,"eglSwapBuffers"); disp->set_eglSwapBuffers((eglSwapBuffers_t)ptr);
+    ptr = dlsym(gles_android,"eglCopyBuffers"); disp->set_eglCopyBuffers((eglCopyBuffers_t)ptr);
+    ptr = dlsym(gles_android,"eglGetProcAddress"); disp->set_eglGetProcAddress((eglGetProcAddress_t)ptr);
+    ptr = dlsym(gles_android,"eglLockSurfaceKHR"); disp->set_eglLockSurfaceKHR((eglLockSurfaceKHR_t)ptr);
+    ptr = dlsym(gles_android,"eglUnlockSurfaceKHR"); disp->set_eglUnlockSurfaceKHR((eglUnlockSurfaceKHR_t)ptr);
+    ptr = dlsym(gles_android,"eglCreateImageKHR"); disp->set_eglCreateImageKHR((eglCreateImageKHR_t)ptr);
+    ptr = dlsym(gles_android,"eglDestroyImageKHR"); disp->set_eglDestroyImageKHR((eglDestroyImageKHR_t)ptr);
+    ptr = dlsym(gles_android,"eglCreateSyncKHR"); disp->set_eglCreateSyncKHR((eglCreateSyncKHR_t)ptr);
+    ptr = dlsym(gles_android,"eglDestroySyncKHR"); disp->set_eglDestroySyncKHR((eglDestroySyncKHR_t)ptr);
+    ptr = dlsym(gles_android,"eglClientWaitSyncKHR"); disp->set_eglClientWaitSyncKHR((eglClientWaitSyncKHR_t)ptr);
+    ptr = dlsym(gles_android,"eglSignalSyncKHR"); disp->set_eglSignalSyncKHR((eglSignalSyncKHR_t)ptr);
+    ptr = dlsym(gles_android,"eglGetSyncAttribKHR"); disp->set_eglGetSyncAttribKHR((eglGetSyncAttribKHR_t)ptr);
+    ptr = dlsym(gles_android,"eglSetSwapRectangleANDROID"); disp->set_eglSetSwapRectangleANDROID((eglSetSwapRectangleANDROID_t)ptr);
+
+        return disp;
+}
diff --git a/opengl/tests/gles_android_wrapper/egl_dispatch.h b/opengl/tests/gles_android_wrapper/egl_dispatch.h
new file mode 100644
index 0000000..1b8de0d
--- /dev/null
+++ b/opengl/tests/gles_android_wrapper/egl_dispatch.h
@@ -0,0 +1,115 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#ifndef _EGL_DISPATCH_H
+#define _EGL_DISPATCH_H
+
+#include "egl_proc.h"
+
+struct egl_dispatch {
+    eglGetError_t eglGetError;
+    eglGetDisplay_t eglGetDisplay;
+    eglInitialize_t eglInitialize;
+    eglTerminate_t eglTerminate;
+    eglQueryString_t eglQueryString;
+    eglGetConfigs_t eglGetConfigs;
+    eglChooseConfig_t eglChooseConfig;
+    eglGetConfigAttrib_t eglGetConfigAttrib;
+    eglCreateWindowSurface_t eglCreateWindowSurface;
+    eglCreatePbufferSurface_t eglCreatePbufferSurface;
+    eglCreatePixmapSurface_t eglCreatePixmapSurface;
+    eglDestroySurface_t eglDestroySurface;
+    eglQuerySurface_t eglQuerySurface;
+    eglBindAPI_t eglBindAPI;
+    eglQueryAPI_t eglQueryAPI;
+    eglWaitClient_t eglWaitClient;
+    eglReleaseThread_t eglReleaseThread;
+    eglCreatePbufferFromClientBuffer_t eglCreatePbufferFromClientBuffer;
+    eglSurfaceAttrib_t eglSurfaceAttrib;
+    eglBindTexImage_t eglBindTexImage;
+    eglReleaseTexImage_t eglReleaseTexImage;
+    eglSwapInterval_t eglSwapInterval;
+    eglCreateContext_t eglCreateContext;
+    eglDestroyContext_t eglDestroyContext;
+    eglMakeCurrent_t eglMakeCurrent;
+    eglGetCurrentContext_t eglGetCurrentContext;
+    eglGetCurrentSurface_t eglGetCurrentSurface;
+    eglGetCurrentDisplay_t eglGetCurrentDisplay;
+    eglQueryContext_t eglQueryContext;
+    eglWaitGL_t eglWaitGL;
+    eglWaitNative_t eglWaitNative;
+    eglSwapBuffers_t eglSwapBuffers;
+    eglCopyBuffers_t eglCopyBuffers;
+    eglGetProcAddress_t eglGetProcAddress;
+    eglLockSurfaceKHR_t eglLockSurfaceKHR;
+    eglUnlockSurfaceKHR_t eglUnlockSurfaceKHR;
+    eglCreateImageKHR_t eglCreateImageKHR;
+    eglDestroyImageKHR_t eglDestroyImageKHR;
+    eglCreateSyncKHR_t eglCreateSyncKHR;
+    eglDestroySyncKHR_t eglDestroySyncKHR;
+    eglClientWaitSyncKHR_t eglClientWaitSyncKHR;
+    eglSignalSyncKHR_t eglSignalSyncKHR;
+    eglGetSyncAttribKHR_t eglGetSyncAttribKHR;
+    eglSetSwapRectangleANDROID_t eglSetSwapRectangleANDROID;
+    //Accessors
+    eglGetError_t set_eglGetError(eglGetError_t f) { eglGetError_t retval = eglGetError; eglGetError = f; return retval;}
+    eglGetDisplay_t set_eglGetDisplay(eglGetDisplay_t f) { eglGetDisplay_t retval = eglGetDisplay; eglGetDisplay = f; return retval;}
+    eglInitialize_t set_eglInitialize(eglInitialize_t f) { eglInitialize_t retval = eglInitialize; eglInitialize = f; return retval;}
+    eglTerminate_t set_eglTerminate(eglTerminate_t f) { eglTerminate_t retval = eglTerminate; eglTerminate = f; return retval;}
+    eglQueryString_t set_eglQueryString(eglQueryString_t f) { eglQueryString_t retval = eglQueryString; eglQueryString = f; return retval;}
+    eglGetConfigs_t set_eglGetConfigs(eglGetConfigs_t f) { eglGetConfigs_t retval = eglGetConfigs; eglGetConfigs = f; return retval;}
+    eglChooseConfig_t set_eglChooseConfig(eglChooseConfig_t f) { eglChooseConfig_t retval = eglChooseConfig; eglChooseConfig = f; return retval;}
+    eglGetConfigAttrib_t set_eglGetConfigAttrib(eglGetConfigAttrib_t f) { eglGetConfigAttrib_t retval = eglGetConfigAttrib; eglGetConfigAttrib = f; return retval;}
+    eglCreateWindowSurface_t set_eglCreateWindowSurface(eglCreateWindowSurface_t f) { eglCreateWindowSurface_t retval = eglCreateWindowSurface; eglCreateWindowSurface = f; return retval;}
+    eglCreatePbufferSurface_t set_eglCreatePbufferSurface(eglCreatePbufferSurface_t f) { eglCreatePbufferSurface_t retval = eglCreatePbufferSurface; eglCreatePbufferSurface = f; return retval;}
+    eglCreatePixmapSurface_t set_eglCreatePixmapSurface(eglCreatePixmapSurface_t f) { eglCreatePixmapSurface_t retval = eglCreatePixmapSurface; eglCreatePixmapSurface = f; return retval;}
+    eglDestroySurface_t set_eglDestroySurface(eglDestroySurface_t f) { eglDestroySurface_t retval = eglDestroySurface; eglDestroySurface = f; return retval;}
+    eglQuerySurface_t set_eglQuerySurface(eglQuerySurface_t f) { eglQuerySurface_t retval = eglQuerySurface; eglQuerySurface = f; return retval;}
+    eglBindAPI_t set_eglBindAPI(eglBindAPI_t f) { eglBindAPI_t retval = eglBindAPI; eglBindAPI = f; return retval;}
+    eglQueryAPI_t set_eglQueryAPI(eglQueryAPI_t f) { eglQueryAPI_t retval = eglQueryAPI; eglQueryAPI = f; return retval;}
+    eglWaitClient_t set_eglWaitClient(eglWaitClient_t f) { eglWaitClient_t retval = eglWaitClient; eglWaitClient = f; return retval;}
+    eglReleaseThread_t set_eglReleaseThread(eglReleaseThread_t f) { eglReleaseThread_t retval = eglReleaseThread; eglReleaseThread = f; return retval;}
+    eglCreatePbufferFromClientBuffer_t set_eglCreatePbufferFromClientBuffer(eglCreatePbufferFromClientBuffer_t f) { eglCreatePbufferFromClientBuffer_t retval = eglCreatePbufferFromClientBuffer; eglCreatePbufferFromClientBuffer = f; return retval;}
+    eglSurfaceAttrib_t set_eglSurfaceAttrib(eglSurfaceAttrib_t f) { eglSurfaceAttrib_t retval = eglSurfaceAttrib; eglSurfaceAttrib = f; return retval;}
+    eglBindTexImage_t set_eglBindTexImage(eglBindTexImage_t f) { eglBindTexImage_t retval = eglBindTexImage; eglBindTexImage = f; return retval;}
+    eglReleaseTexImage_t set_eglReleaseTexImage(eglReleaseTexImage_t f) { eglReleaseTexImage_t retval = eglReleaseTexImage; eglReleaseTexImage = f; return retval;}
+    eglSwapInterval_t set_eglSwapInterval(eglSwapInterval_t f) { eglSwapInterval_t retval = eglSwapInterval; eglSwapInterval = f; return retval;}
+    eglCreateContext_t set_eglCreateContext(eglCreateContext_t f) { eglCreateContext_t retval = eglCreateContext; eglCreateContext = f; return retval;}
+    eglDestroyContext_t set_eglDestroyContext(eglDestroyContext_t f) { eglDestroyContext_t retval = eglDestroyContext; eglDestroyContext = f; return retval;}
+    eglMakeCurrent_t set_eglMakeCurrent(eglMakeCurrent_t f) { eglMakeCurrent_t retval = eglMakeCurrent; eglMakeCurrent = f; return retval;}
+    eglGetCurrentContext_t set_eglGetCurrentContext(eglGetCurrentContext_t f) { eglGetCurrentContext_t retval = eglGetCurrentContext; eglGetCurrentContext = f; return retval;}
+    eglGetCurrentSurface_t set_eglGetCurrentSurface(eglGetCurrentSurface_t f) { eglGetCurrentSurface_t retval = eglGetCurrentSurface; eglGetCurrentSurface = f; return retval;}
+    eglGetCurrentDisplay_t set_eglGetCurrentDisplay(eglGetCurrentDisplay_t f) { eglGetCurrentDisplay_t retval = eglGetCurrentDisplay; eglGetCurrentDisplay = f; return retval;}
+    eglQueryContext_t set_eglQueryContext(eglQueryContext_t f) { eglQueryContext_t retval = eglQueryContext; eglQueryContext = f; return retval;}
+    eglWaitGL_t set_eglWaitGL(eglWaitGL_t f) { eglWaitGL_t retval = eglWaitGL; eglWaitGL = f; return retval;}
+    eglWaitNative_t set_eglWaitNative(eglWaitNative_t f) { eglWaitNative_t retval = eglWaitNative; eglWaitNative = f; return retval;}
+    eglSwapBuffers_t set_eglSwapBuffers(eglSwapBuffers_t f) { eglSwapBuffers_t retval = eglSwapBuffers; eglSwapBuffers = f; return retval;}
+    eglCopyBuffers_t set_eglCopyBuffers(eglCopyBuffers_t f) { eglCopyBuffers_t retval = eglCopyBuffers; eglCopyBuffers = f; return retval;}
+    eglGetProcAddress_t set_eglGetProcAddress(eglGetProcAddress_t f) { eglGetProcAddress_t retval = eglGetProcAddress; eglGetProcAddress = f; return retval;}
+    eglLockSurfaceKHR_t set_eglLockSurfaceKHR(eglLockSurfaceKHR_t f) { eglLockSurfaceKHR_t retval = eglLockSurfaceKHR; eglLockSurfaceKHR = f; return retval;}
+    eglUnlockSurfaceKHR_t set_eglUnlockSurfaceKHR(eglUnlockSurfaceKHR_t f) { eglUnlockSurfaceKHR_t retval = eglUnlockSurfaceKHR; eglUnlockSurfaceKHR = f; return retval;}
+    eglCreateImageKHR_t set_eglCreateImageKHR(eglCreateImageKHR_t f) { eglCreateImageKHR_t retval = eglCreateImageKHR; eglCreateImageKHR = f; return retval;}
+    eglDestroyImageKHR_t set_eglDestroyImageKHR(eglDestroyImageKHR_t f) { eglDestroyImageKHR_t retval = eglDestroyImageKHR; eglDestroyImageKHR = f; return retval;}
+    eglCreateSyncKHR_t set_eglCreateSyncKHR(eglCreateSyncKHR_t f) { eglCreateSyncKHR_t retval = eglCreateSyncKHR; eglCreateSyncKHR = f; return retval;}
+    eglDestroySyncKHR_t set_eglDestroySyncKHR(eglDestroySyncKHR_t f) { eglDestroySyncKHR_t retval = eglDestroySyncKHR; eglDestroySyncKHR = f; return retval;}
+    eglClientWaitSyncKHR_t set_eglClientWaitSyncKHR(eglClientWaitSyncKHR_t f) { eglClientWaitSyncKHR_t retval = eglClientWaitSyncKHR; eglClientWaitSyncKHR = f; return retval;}
+    eglSignalSyncKHR_t set_eglSignalSyncKHR(eglSignalSyncKHR_t f) { eglSignalSyncKHR_t retval = eglSignalSyncKHR; eglSignalSyncKHR = f; return retval;}
+    eglGetSyncAttribKHR_t set_eglGetSyncAttribKHR(eglGetSyncAttribKHR_t f) { eglGetSyncAttribKHR_t retval = eglGetSyncAttribKHR; eglGetSyncAttribKHR = f; return retval;}
+    eglSetSwapRectangleANDROID_t set_eglSetSwapRectangleANDROID(eglSetSwapRectangleANDROID_t f) { eglSetSwapRectangleANDROID_t retval = eglSetSwapRectangleANDROID; eglSetSwapRectangleANDROID = f; return retval;}
+};
+
+egl_dispatch *create_egl_dispatch(void *gles_andorid);
+
+#endif
diff --git a/opengl/tests/gles_android_wrapper/egl_ftable.h b/opengl/tests/gles_android_wrapper/egl_ftable.h
new file mode 100644
index 0000000..ee40585
--- /dev/null
+++ b/opengl/tests/gles_android_wrapper/egl_ftable.h
@@ -0,0 +1,66 @@
+/*
+* Copyright (C) 2011 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.
+*/
+static struct _egl_funcs_by_name {
+    const char *name;
+    void *proc;
+} egl_funcs_by_name[] = {
+    {"eglGetError", (void *)eglGetError},
+    {"eglGetDisplay", (void *)eglGetDisplay},
+    {"eglInitialize", (void *)eglInitialize},
+    {"eglTerminate", (void *)eglTerminate},
+    {"eglQueryString", (void *)eglQueryString},
+    {"eglGetConfigs", (void *)eglGetConfigs},
+    {"eglChooseConfig", (void *)eglChooseConfig},
+    {"eglGetConfigAttrib", (void *)eglGetConfigAttrib},
+    {"eglCreateWindowSurface", (void *)eglCreateWindowSurface},
+    {"eglCreatePbufferSurface", (void *)eglCreatePbufferSurface},
+    {"eglCreatePixmapSurface", (void *)eglCreatePixmapSurface},
+    {"eglDestroySurface", (void *)eglDestroySurface},
+    {"eglQuerySurface", (void *)eglQuerySurface},
+    {"eglBindAPI", (void *)eglBindAPI},
+    {"eglQueryAPI", (void *)eglQueryAPI},
+    {"eglWaitClient", (void *)eglWaitClient},
+    {"eglReleaseThread", (void *)eglReleaseThread},
+    {"eglCreatePbufferFromClientBuffer", (void *)eglCreatePbufferFromClientBuffer},
+    {"eglSurfaceAttrib", (void *)eglSurfaceAttrib},
+    {"eglBindTexImage", (void *)eglBindTexImage},
+    {"eglReleaseTexImage", (void *)eglReleaseTexImage},
+    {"eglSwapInterval", (void *)eglSwapInterval},
+    {"eglCreateContext", (void *)eglCreateContext},
+    {"eglDestroyContext", (void *)eglDestroyContext},
+    {"eglMakeCurrent", (void *)eglMakeCurrent},
+    {"eglGetCurrentContext", (void *)eglGetCurrentContext},
+    {"eglGetCurrentSurface", (void *)eglGetCurrentSurface},
+    {"eglGetCurrentDisplay", (void *)eglGetCurrentDisplay},
+    {"eglQueryContext", (void *)eglQueryContext},
+    {"eglWaitGL", (void *)eglWaitGL},
+    {"eglWaitNative", (void *)eglWaitNative},
+    {"eglSwapBuffers", (void *)eglSwapBuffers},
+    {"eglCopyBuffers", (void *)eglCopyBuffers},
+    {"eglGetProcAddress", (void *)eglGetProcAddress},
+    {"eglLockSurfaceKHR", (void *)eglLockSurfaceKHR},
+    {"eglUnlockSurfaceKHR", (void *)eglUnlockSurfaceKHR},
+    {"eglCreateImageKHR", (void *)eglCreateImageKHR},
+    {"eglDestroyImageKHR", (void *)eglDestroyImageKHR},
+    {"eglCreateSyncKHR", (void *)eglCreateSyncKHR},
+    {"eglDestroySyncKHR", (void *)eglDestroySyncKHR},
+    {"eglClientWaitSyncKHR", (void *)eglClientWaitSyncKHR},
+    {"eglSignalSyncKHR", (void *)eglSignalSyncKHR},
+    {"eglGetSyncAttribKHR", (void *)eglGetSyncAttribKHR},
+    {"eglSetSwapRectangleANDROID", (void *)eglSetSwapRectangleANDROID}
+};
+
+static int egl_num_funcs = sizeof(egl_funcs_by_name) / sizeof(struct _egl_funcs_by_name);
diff --git a/opengl/tests/gles_android_wrapper/egl_proc.h b/opengl/tests/gles_android_wrapper/egl_proc.h
new file mode 100644
index 0000000..140c030
--- /dev/null
+++ b/opengl/tests/gles_android_wrapper/egl_proc.h
@@ -0,0 +1,68 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#ifndef _EGL_PROC_H
+#define _EGL_PROC_H
+
+#include <EGL/egl.h>
+#define EGL_EGLEXT_PROTOTYPES
+#include <EGL/eglext.h>
+
+typedef EGLint (* eglGetError_t) ();
+typedef EGLDisplay (* eglGetDisplay_t) (EGLNativeDisplayType);
+typedef EGLBoolean (* eglInitialize_t) (EGLDisplay, EGLint*, EGLint*);
+typedef EGLBoolean (* eglTerminate_t) (EGLDisplay);
+typedef char* (* eglQueryString_t) (EGLDisplay, EGLint);
+typedef EGLBoolean (* eglGetConfigs_t) (EGLDisplay, EGLConfig*, EGLint, EGLint*);
+typedef EGLBoolean (* eglChooseConfig_t) (EGLDisplay, const EGLint*, EGLConfig*, EGLint, EGLint*);
+typedef EGLBoolean (* eglGetConfigAttrib_t) (EGLDisplay, EGLConfig, EGLint, EGLint*);
+typedef EGLSurface (* eglCreateWindowSurface_t) (EGLDisplay, EGLConfig, EGLNativeWindowType, const EGLint*);
+typedef EGLSurface (* eglCreatePbufferSurface_t) (EGLDisplay, EGLConfig, const EGLint*);
+typedef EGLSurface (* eglCreatePixmapSurface_t) (EGLDisplay, EGLConfig, EGLNativePixmapType, const EGLint*);
+typedef EGLBoolean (* eglDestroySurface_t) (EGLDisplay, EGLSurface);
+typedef EGLBoolean (* eglQuerySurface_t) (EGLDisplay, EGLSurface, EGLint, EGLint*);
+typedef EGLBoolean (* eglBindAPI_t) (EGLenum);
+typedef EGLenum (* eglQueryAPI_t) ();
+typedef EGLBoolean (* eglWaitClient_t) ();
+typedef EGLBoolean (* eglReleaseThread_t) ();
+typedef EGLSurface (* eglCreatePbufferFromClientBuffer_t) (EGLDisplay, EGLenum, EGLClientBuffer, EGLConfig, const EGLint*);
+typedef EGLBoolean (* eglSurfaceAttrib_t) (EGLDisplay, EGLSurface, EGLint, EGLint);
+typedef EGLBoolean (* eglBindTexImage_t) (EGLDisplay, EGLSurface, EGLint);
+typedef EGLBoolean (* eglReleaseTexImage_t) (EGLDisplay, EGLSurface, EGLint);
+typedef EGLBoolean (* eglSwapInterval_t) (EGLDisplay, EGLint);
+typedef EGLContext (* eglCreateContext_t) (EGLDisplay, EGLConfig, EGLContext, const EGLint*);
+typedef EGLBoolean (* eglDestroyContext_t) (EGLDisplay, EGLContext);
+typedef EGLBoolean (* eglMakeCurrent_t) (EGLDisplay, EGLSurface, EGLSurface, EGLContext);
+typedef EGLContext (* eglGetCurrentContext_t) ();
+typedef EGLSurface (* eglGetCurrentSurface_t) (EGLint);
+typedef EGLDisplay (* eglGetCurrentDisplay_t) ();
+typedef EGLBoolean (* eglQueryContext_t) (EGLDisplay, EGLContext, EGLint, EGLint*);
+typedef EGLBoolean (* eglWaitGL_t) ();
+typedef EGLBoolean (* eglWaitNative_t) (EGLint);
+typedef EGLBoolean (* eglSwapBuffers_t) (EGLDisplay, EGLSurface);
+typedef EGLBoolean (* eglCopyBuffers_t) (EGLDisplay, EGLSurface, EGLNativePixmapType);
+typedef __eglMustCastToProperFunctionPointerType (* eglGetProcAddress_t) (const char*);
+typedef EGLBoolean (* eglLockSurfaceKHR_t) (EGLDisplay, EGLSurface, const EGLint*);
+typedef EGLBoolean (* eglUnlockSurfaceKHR_t) (EGLDisplay, EGLSurface);
+typedef EGLImageKHR (* eglCreateImageKHR_t) (EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, const EGLint*);
+typedef EGLBoolean (* eglDestroyImageKHR_t) (EGLDisplay, EGLImageKHR image);
+typedef EGLSyncKHR (* eglCreateSyncKHR_t) (EGLDisplay, EGLenum, const EGLint*);
+typedef EGLBoolean (* eglDestroySyncKHR_t) (EGLDisplay, EGLSyncKHR sync);
+typedef EGLint (* eglClientWaitSyncKHR_t) (EGLDisplay, EGLSyncKHR, EGLint, EGLTimeKHR timeout);
+typedef EGLBoolean (* eglSignalSyncKHR_t) (EGLDisplay, EGLSyncKHR, EGLenum);
+typedef EGLBoolean (* eglGetSyncAttribKHR_t) (EGLDisplay, EGLSyncKHR, EGLint, EGLint*);
+typedef EGLBoolean (* eglSetSwapRectangleANDROID_t) (EGLDisplay, EGLSurface, EGLint, EGLint, EGLint, EGLint);
+
+#endif // of  _EGL_PROC_H
diff --git a/opengl/tests/gles_android_wrapper/gles.cpp b/opengl/tests/gles_android_wrapper/gles.cpp
new file mode 100644
index 0000000..c0949c8
--- /dev/null
+++ b/opengl/tests/gles_android_wrapper/gles.cpp
@@ -0,0 +1,1410 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "gles_dispatch.h"
+#include "gles_ftable.h"
+#include <EGL/egl.h>
+#include <cutils/log.h>
+
+static struct gles_dispatch *s_dispatch = NULL;
+
+void init_gles(void *gles_android)
+{
+    s_dispatch = create_gles_dispatch(gles_android);
+    if (s_dispatch == NULL) {
+        ALOGE("failed to create gles dispatch\n");
+    }
+}
+
+static struct gles_dispatch *getDispatch()
+{
+    if (!s_dispatch) {
+        fprintf(stderr,"FATAL ERROR: GLES has not been initialized\n");
+        exit(-1);
+    }
+
+    return s_dispatch;
+}
+
+__eglMustCastToProperFunctionPointerType gles_getProcAddress(const char *procname)
+{
+     for (int i=0; i<gles_num_funcs; i++) {
+         if (!strcmp(gles_funcs_by_name[i].name, procname)) {
+             return (__eglMustCastToProperFunctionPointerType)gles_funcs_by_name[i].proc;
+         }
+     }
+
+     return NULL;
+}
+
+///////////// Path-through functions ///////////////
+void glAlphaFunc(GLenum func, GLclampf ref)
+{
+     getDispatch()->glAlphaFunc(func, ref);
+}
+
+void glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+     getDispatch()->glClearColor(red, green, blue, alpha);
+}
+
+void glClearDepthf(GLclampf depth)
+{
+     getDispatch()->glClearDepthf(depth);
+}
+
+void glClipPlanef(GLenum plane, const GLfloat *equation)
+{
+     getDispatch()->glClipPlanef(plane, equation);
+}
+
+void glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+{
+     getDispatch()->glColor4f(red, green, blue, alpha);
+}
+
+void glDepthRangef(GLclampf zNear, GLclampf zFar)
+{
+     getDispatch()->glDepthRangef(zNear, zFar);
+}
+
+void glFogf(GLenum pname, GLfloat param)
+{
+     getDispatch()->glFogf(pname, param);
+}
+
+void glFogfv(GLenum pname, const GLfloat *params)
+{
+     getDispatch()->glFogfv(pname, params);
+}
+
+void glFrustumf(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
+{
+     getDispatch()->glFrustumf(left, right, bottom, top, zNear, zFar);
+}
+
+void glGetClipPlanef(GLenum pname, GLfloat eqn[4])
+{
+     getDispatch()->glGetClipPlanef(pname, eqn);
+}
+
+void glGetFloatv(GLenum pname, GLfloat *params)
+{
+     getDispatch()->glGetFloatv(pname, params);
+}
+
+void glGetLightfv(GLenum light, GLenum pname, GLfloat *params)
+{
+     getDispatch()->glGetLightfv(light, pname, params);
+}
+
+void glGetMaterialfv(GLenum face, GLenum pname, GLfloat *params)
+{
+     getDispatch()->glGetMaterialfv(face, pname, params);
+}
+
+void glGetTexEnvfv(GLenum env, GLenum pname, GLfloat *params)
+{
+     getDispatch()->glGetTexEnvfv(env, pname, params);
+}
+
+void glGetTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
+{
+     getDispatch()->glGetTexParameterfv(target, pname, params);
+}
+
+void glLightModelf(GLenum pname, GLfloat param)
+{
+     getDispatch()->glLightModelf(pname, param);
+}
+
+void glLightModelfv(GLenum pname, const GLfloat *params)
+{
+     getDispatch()->glLightModelfv(pname, params);
+}
+
+void glLightf(GLenum light, GLenum pname, GLfloat param)
+{
+     getDispatch()->glLightf(light, pname, param);
+}
+
+void glLightfv(GLenum light, GLenum pname, const GLfloat *params)
+{
+     getDispatch()->glLightfv(light, pname, params);
+}
+
+void glLineWidth(GLfloat width)
+{
+     getDispatch()->glLineWidth(width);
+}
+
+void glLoadMatrixf(const GLfloat *m)
+{
+     getDispatch()->glLoadMatrixf(m);
+}
+
+void glMaterialf(GLenum face, GLenum pname, GLfloat param)
+{
+     getDispatch()->glMaterialf(face, pname, param);
+}
+
+void glMaterialfv(GLenum face, GLenum pname, const GLfloat *params)
+{
+     getDispatch()->glMaterialfv(face, pname, params);
+}
+
+void glMultMatrixf(const GLfloat *m)
+{
+     getDispatch()->glMultMatrixf(m);
+}
+
+void glMultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
+{
+     getDispatch()->glMultiTexCoord4f(target, s, t, r, q);
+}
+
+void glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz)
+{
+     getDispatch()->glNormal3f(nx, ny, nz);
+}
+
+void glOrthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
+{
+     getDispatch()->glOrthof(left, right, bottom, top, zNear, zFar);
+}
+
+void glPointParameterf(GLenum pname, GLfloat param)
+{
+     getDispatch()->glPointParameterf(pname, param);
+}
+
+void glPointParameterfv(GLenum pname, const GLfloat *params)
+{
+     getDispatch()->glPointParameterfv(pname, params);
+}
+
+void glPointSize(GLfloat size)
+{
+     getDispatch()->glPointSize(size);
+}
+
+void glPolygonOffset(GLfloat factor, GLfloat units)
+{
+     getDispatch()->glPolygonOffset(factor, units);
+}
+
+void glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
+{
+     getDispatch()->glRotatef(angle, x, y, z);
+}
+
+void glScalef(GLfloat x, GLfloat y, GLfloat z)
+{
+     getDispatch()->glScalef(x, y, z);
+}
+
+void glTexEnvf(GLenum target, GLenum pname, GLfloat param)
+{
+     getDispatch()->glTexEnvf(target, pname, param);
+}
+
+void glTexEnvfv(GLenum target, GLenum pname, const GLfloat *params)
+{
+     getDispatch()->glTexEnvfv(target, pname, params);
+}
+
+void glTexParameterf(GLenum target, GLenum pname, GLfloat param)
+{
+     getDispatch()->glTexParameterf(target, pname, param);
+}
+
+void glTexParameterfv(GLenum target, GLenum pname, const GLfloat *params)
+{
+     getDispatch()->glTexParameterfv(target, pname, params);
+}
+
+void glTranslatef(GLfloat x, GLfloat y, GLfloat z)
+{
+     getDispatch()->glTranslatef(x, y, z);
+}
+
+void glActiveTexture(GLenum texture)
+{
+     getDispatch()->glActiveTexture(texture);
+}
+
+void glAlphaFuncx(GLenum func, GLclampx ref)
+{
+     getDispatch()->glAlphaFuncx(func, ref);
+}
+
+void glBindBuffer(GLenum target, GLuint buffer)
+{
+     getDispatch()->glBindBuffer(target, buffer);
+}
+
+void glBindTexture(GLenum target, GLuint texture)
+{
+     getDispatch()->glBindTexture(target, texture);
+}
+
+void glBlendFunc(GLenum sfactor, GLenum dfactor)
+{
+     getDispatch()->glBlendFunc(sfactor, dfactor);
+}
+
+void glBufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
+{
+     getDispatch()->glBufferData(target, size, data, usage);
+}
+
+void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
+{
+     getDispatch()->glBufferSubData(target, offset, size, data);
+}
+
+void glClear(GLbitfield mask)
+{
+     getDispatch()->glClear(mask);
+}
+
+void glClearColorx(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha)
+{
+     getDispatch()->glClearColorx(red, green, blue, alpha);
+}
+
+void glClearDepthx(GLclampx depth)
+{
+     getDispatch()->glClearDepthx(depth);
+}
+
+void glClearStencil(GLint s)
+{
+     getDispatch()->glClearStencil(s);
+}
+
+void glClientActiveTexture(GLenum texture)
+{
+     getDispatch()->glClientActiveTexture(texture);
+}
+
+void glClipPlanex(GLenum plane, const GLfixed *equation)
+{
+     getDispatch()->glClipPlanex(plane, equation);
+}
+
+void glColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
+{
+     getDispatch()->glColor4ub(red, green, blue, alpha);
+}
+
+void glColor4x(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)
+{
+     getDispatch()->glColor4x(red, green, blue, alpha);
+}
+
+void glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
+{
+     getDispatch()->glColorMask(red, green, blue, alpha);
+}
+
+void glColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+     getDispatch()->glColorPointer(size, type, stride, pointer);
+}
+
+void glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data)
+{
+     getDispatch()->glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);
+}
+
+void glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data)
+{
+     getDispatch()->glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data);
+}
+
+void glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
+{
+     getDispatch()->glCopyTexImage2D(target, level, internalformat, x, y, width, height, border);
+}
+
+void glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+{
+     getDispatch()->glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
+}
+
+void glCullFace(GLenum mode)
+{
+     getDispatch()->glCullFace(mode);
+}
+
+void glDeleteBuffers(GLsizei n, const GLuint *buffers)
+{
+     getDispatch()->glDeleteBuffers(n, buffers);
+}
+
+void glDeleteTextures(GLsizei n, const GLuint *textures)
+{
+     getDispatch()->glDeleteTextures(n, textures);
+}
+
+void glDepthFunc(GLenum func)
+{
+     getDispatch()->glDepthFunc(func);
+}
+
+void glDepthMask(GLboolean flag)
+{
+     getDispatch()->glDepthMask(flag);
+}
+
+void glDepthRangex(GLclampx zNear, GLclampx zFar)
+{
+     getDispatch()->glDepthRangex(zNear, zFar);
+}
+
+void glDisable(GLenum cap)
+{
+     getDispatch()->glDisable(cap);
+}
+
+void glDisableClientState(GLenum array)
+{
+     getDispatch()->glDisableClientState(array);
+}
+
+void glDrawArrays(GLenum mode, GLint first, GLsizei count)
+{
+     getDispatch()->glDrawArrays(mode, first, count);
+}
+
+void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)
+{
+     getDispatch()->glDrawElements(mode, count, type, indices);
+}
+
+void glEnable(GLenum cap)
+{
+     getDispatch()->glEnable(cap);
+}
+
+void glEnableClientState(GLenum array)
+{
+     getDispatch()->glEnableClientState(array);
+}
+
+void glFinish()
+{
+     getDispatch()->glFinish();
+}
+
+void glFlush()
+{
+     getDispatch()->glFlush();
+}
+
+void glFogx(GLenum pname, GLfixed param)
+{
+     getDispatch()->glFogx(pname, param);
+}
+
+void glFogxv(GLenum pname, const GLfixed *params)
+{
+     getDispatch()->glFogxv(pname, params);
+}
+
+void glFrontFace(GLenum mode)
+{
+     getDispatch()->glFrontFace(mode);
+}
+
+void glFrustumx(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
+{
+     getDispatch()->glFrustumx(left, right, bottom, top, zNear, zFar);
+}
+
+void glGetBooleanv(GLenum pname, GLboolean *params)
+{
+     getDispatch()->glGetBooleanv(pname, params);
+}
+
+void glGetBufferParameteriv(GLenum target, GLenum pname, GLint *params)
+{
+     getDispatch()->glGetBufferParameteriv(target, pname, params);
+}
+
+void glGetClipPlanex(GLenum pname, GLfixed eqn[4])
+{
+     getDispatch()->glGetClipPlanex(pname, eqn);
+}
+
+void glGenBuffers(GLsizei n, GLuint *buffers)
+{
+     getDispatch()->glGenBuffers(n, buffers);
+}
+
+void glGenTextures(GLsizei n, GLuint *textures)
+{
+     getDispatch()->glGenTextures(n, textures);
+}
+
+GLenum glGetError()
+{
+     return getDispatch()->glGetError();
+}
+
+void glGetFixedv(GLenum pname, GLfixed *params)
+{
+     getDispatch()->glGetFixedv(pname, params);
+}
+
+void glGetIntegerv(GLenum pname, GLint *params)
+{
+     getDispatch()->glGetIntegerv(pname, params);
+}
+
+void glGetLightxv(GLenum light, GLenum pname, GLfixed *params)
+{
+     getDispatch()->glGetLightxv(light, pname, params);
+}
+
+void glGetMaterialxv(GLenum face, GLenum pname, GLfixed *params)
+{
+     getDispatch()->glGetMaterialxv(face, pname, params);
+}
+
+void glGetPointerv(GLenum pname, GLvoid **params)
+{
+     getDispatch()->glGetPointerv(pname, params);
+}
+
+const GLubyte* glGetString(GLenum name)
+{
+     return getDispatch()->glGetString(name);
+}
+
+void glGetTexEnviv(GLenum env, GLenum pname, GLint *params)
+{
+     getDispatch()->glGetTexEnviv(env, pname, params);
+}
+
+void glGetTexEnvxv(GLenum env, GLenum pname, GLfixed *params)
+{
+     getDispatch()->glGetTexEnvxv(env, pname, params);
+}
+
+void glGetTexParameteriv(GLenum target, GLenum pname, GLint *params)
+{
+     getDispatch()->glGetTexParameteriv(target, pname, params);
+}
+
+void glGetTexParameterxv(GLenum target, GLenum pname, GLfixed *params)
+{
+     getDispatch()->glGetTexParameterxv(target, pname, params);
+}
+
+void glHint(GLenum target, GLenum mode)
+{
+     getDispatch()->glHint(target, mode);
+}
+
+GLboolean glIsBuffer(GLuint buffer)
+{
+     return getDispatch()->glIsBuffer(buffer);
+}
+
+GLboolean glIsEnabled(GLenum cap)
+{
+     return getDispatch()->glIsEnabled(cap);
+}
+
+GLboolean glIsTexture(GLuint texture)
+{
+     return getDispatch()->glIsTexture(texture);
+}
+
+void glLightModelx(GLenum pname, GLfixed param)
+{
+     getDispatch()->glLightModelx(pname, param);
+}
+
+void glLightModelxv(GLenum pname, const GLfixed *params)
+{
+     getDispatch()->glLightModelxv(pname, params);
+}
+
+void glLightx(GLenum light, GLenum pname, GLfixed param)
+{
+     getDispatch()->glLightx(light, pname, param);
+}
+
+void glLightxv(GLenum light, GLenum pname, const GLfixed *params)
+{
+     getDispatch()->glLightxv(light, pname, params);
+}
+
+void glLineWidthx(GLfixed width)
+{
+     getDispatch()->glLineWidthx(width);
+}
+
+void glLoadIdentity()
+{
+     getDispatch()->glLoadIdentity();
+}
+
+void glLoadMatrixx(const GLfixed *m)
+{
+     getDispatch()->glLoadMatrixx(m);
+}
+
+void glLogicOp(GLenum opcode)
+{
+     getDispatch()->glLogicOp(opcode);
+}
+
+void glMaterialx(GLenum face, GLenum pname, GLfixed param)
+{
+     getDispatch()->glMaterialx(face, pname, param);
+}
+
+void glMaterialxv(GLenum face, GLenum pname, const GLfixed *params)
+{
+     getDispatch()->glMaterialxv(face, pname, params);
+}
+
+void glMatrixMode(GLenum mode)
+{
+     getDispatch()->glMatrixMode(mode);
+}
+
+void glMultMatrixx(const GLfixed *m)
+{
+     getDispatch()->glMultMatrixx(m);
+}
+
+void glMultiTexCoord4x(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q)
+{
+     getDispatch()->glMultiTexCoord4x(target, s, t, r, q);
+}
+
+void glNormal3x(GLfixed nx, GLfixed ny, GLfixed nz)
+{
+     getDispatch()->glNormal3x(nx, ny, nz);
+}
+
+void glNormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+     getDispatch()->glNormalPointer(type, stride, pointer);
+}
+
+void glOrthox(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
+{
+     getDispatch()->glOrthox(left, right, bottom, top, zNear, zFar);
+}
+
+void glPixelStorei(GLenum pname, GLint param)
+{
+     getDispatch()->glPixelStorei(pname, param);
+}
+
+void glPointParameterx(GLenum pname, GLfixed param)
+{
+     getDispatch()->glPointParameterx(pname, param);
+}
+
+void glPointParameterxv(GLenum pname, const GLfixed *params)
+{
+     getDispatch()->glPointParameterxv(pname, params);
+}
+
+void glPointSizex(GLfixed size)
+{
+     getDispatch()->glPointSizex(size);
+}
+
+void glPolygonOffsetx(GLfixed factor, GLfixed units)
+{
+     getDispatch()->glPolygonOffsetx(factor, units);
+}
+
+void glPopMatrix()
+{
+     getDispatch()->glPopMatrix();
+}
+
+void glPushMatrix()
+{
+     getDispatch()->glPushMatrix();
+}
+
+void glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels)
+{
+     getDispatch()->glReadPixels(x, y, width, height, format, type, pixels);
+}
+
+void glRotatex(GLfixed angle, GLfixed x, GLfixed y, GLfixed z)
+{
+     getDispatch()->glRotatex(angle, x, y, z);
+}
+
+void glSampleCoverage(GLclampf value, GLboolean invert)
+{
+     getDispatch()->glSampleCoverage(value, invert);
+}
+
+void glSampleCoveragex(GLclampx value, GLboolean invert)
+{
+     getDispatch()->glSampleCoveragex(value, invert);
+}
+
+void glScalex(GLfixed x, GLfixed y, GLfixed z)
+{
+     getDispatch()->glScalex(x, y, z);
+}
+
+void glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+     getDispatch()->glScissor(x, y, width, height);
+}
+
+void glShadeModel(GLenum mode)
+{
+     getDispatch()->glShadeModel(mode);
+}
+
+void glStencilFunc(GLenum func, GLint ref, GLuint mask)
+{
+     getDispatch()->glStencilFunc(func, ref, mask);
+}
+
+void glStencilMask(GLuint mask)
+{
+     getDispatch()->glStencilMask(mask);
+}
+
+void glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
+{
+     getDispatch()->glStencilOp(fail, zfail, zpass);
+}
+
+void glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+     getDispatch()->glTexCoordPointer(size, type, stride, pointer);
+}
+
+void glTexEnvi(GLenum target, GLenum pname, GLint param)
+{
+     getDispatch()->glTexEnvi(target, pname, param);
+}
+
+void glTexEnvx(GLenum target, GLenum pname, GLfixed param)
+{
+     getDispatch()->glTexEnvx(target, pname, param);
+}
+
+void glTexEnviv(GLenum target, GLenum pname, const GLint *params)
+{
+     getDispatch()->glTexEnviv(target, pname, params);
+}
+
+void glTexEnvxv(GLenum target, GLenum pname, const GLfixed *params)
+{
+     getDispatch()->glTexEnvxv(target, pname, params);
+}
+
+void glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+     getDispatch()->glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
+}
+
+void glTexParameteri(GLenum target, GLenum pname, GLint param)
+{
+     getDispatch()->glTexParameteri(target, pname, param);
+}
+
+void glTexParameterx(GLenum target, GLenum pname, GLfixed param)
+{
+     getDispatch()->glTexParameterx(target, pname, param);
+}
+
+void glTexParameteriv(GLenum target, GLenum pname, const GLint *params)
+{
+     getDispatch()->glTexParameteriv(target, pname, params);
+}
+
+void glTexParameterxv(GLenum target, GLenum pname, const GLfixed *params)
+{
+     getDispatch()->glTexParameterxv(target, pname, params);
+}
+
+void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
+{
+     getDispatch()->glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
+}
+
+void glTranslatex(GLfixed x, GLfixed y, GLfixed z)
+{
+     getDispatch()->glTranslatex(x, y, z);
+}
+
+void glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+     getDispatch()->glVertexPointer(size, type, stride, pointer);
+}
+
+void glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+     getDispatch()->glViewport(x, y, width, height);
+}
+
+void glPointSizePointerOES(GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+     getDispatch()->glPointSizePointerOES(type, stride, pointer);
+}
+
+void glBlendEquationSeparateOES(GLenum modeRGB, GLenum modeAlpha)
+{
+     getDispatch()->glBlendEquationSeparateOES(modeRGB, modeAlpha);
+}
+
+void glBlendFuncSeparateOES(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+{
+     getDispatch()->glBlendFuncSeparateOES(srcRGB, dstRGB, srcAlpha, dstAlpha);
+}
+
+void glBlendEquationOES(GLenum mode)
+{
+     getDispatch()->glBlendEquationOES(mode);
+}
+
+void glDrawTexsOES(GLshort x, GLshort y, GLshort z, GLshort width, GLshort height)
+{
+     getDispatch()->glDrawTexsOES(x, y, z, width, height);
+}
+
+void glDrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height)
+{
+     getDispatch()->glDrawTexiOES(x, y, z, width, height);
+}
+
+void glDrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height)
+{
+     getDispatch()->glDrawTexxOES(x, y, z, width, height);
+}
+
+void glDrawTexsvOES(const GLshort *coords)
+{
+     getDispatch()->glDrawTexsvOES(coords);
+}
+
+void glDrawTexivOES(const GLint *coords)
+{
+     getDispatch()->glDrawTexivOES(coords);
+}
+
+void glDrawTexxvOES(const GLfixed *coords)
+{
+     getDispatch()->glDrawTexxvOES(coords);
+}
+
+void glDrawTexfOES(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height)
+{
+     getDispatch()->glDrawTexfOES(x, y, z, width, height);
+}
+
+void glDrawTexfvOES(const GLfloat *coords)
+{
+     getDispatch()->glDrawTexfvOES(coords);
+}
+
+void glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
+{
+     getDispatch()->glEGLImageTargetTexture2DOES(target, image);
+}
+
+void glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
+{
+     getDispatch()->glEGLImageTargetRenderbufferStorageOES(target, image);
+}
+
+void glAlphaFuncxOES(GLenum func, GLclampx ref)
+{
+     getDispatch()->glAlphaFuncxOES(func, ref);
+}
+
+void glClearColorxOES(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha)
+{
+     getDispatch()->glClearColorxOES(red, green, blue, alpha);
+}
+
+void glClearDepthxOES(GLclampx depth)
+{
+     getDispatch()->glClearDepthxOES(depth);
+}
+
+void glClipPlanexOES(GLenum plane, const GLfixed *equation)
+{
+     getDispatch()->glClipPlanexOES(plane, equation);
+}
+
+void glColor4xOES(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)
+{
+     getDispatch()->glColor4xOES(red, green, blue, alpha);
+}
+
+void glDepthRangexOES(GLclampx zNear, GLclampx zFar)
+{
+     getDispatch()->glDepthRangexOES(zNear, zFar);
+}
+
+void glFogxOES(GLenum pname, GLfixed param)
+{
+     getDispatch()->glFogxOES(pname, param);
+}
+
+void glFogxvOES(GLenum pname, const GLfixed *params)
+{
+     getDispatch()->glFogxvOES(pname, params);
+}
+
+void glFrustumxOES(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
+{
+     getDispatch()->glFrustumxOES(left, right, bottom, top, zNear, zFar);
+}
+
+void glGetClipPlanexOES(GLenum pname, GLfixed eqn[4])
+{
+     getDispatch()->glGetClipPlanexOES(pname, eqn);
+}
+
+void glGetFixedvOES(GLenum pname, GLfixed *params)
+{
+     getDispatch()->glGetFixedvOES(pname, params);
+}
+
+void glGetLightxvOES(GLenum light, GLenum pname, GLfixed *params)
+{
+     getDispatch()->glGetLightxvOES(light, pname, params);
+}
+
+void glGetMaterialxvOES(GLenum face, GLenum pname, GLfixed *params)
+{
+     getDispatch()->glGetMaterialxvOES(face, pname, params);
+}
+
+void glGetTexEnvxvOES(GLenum env, GLenum pname, GLfixed *params)
+{
+     getDispatch()->glGetTexEnvxvOES(env, pname, params);
+}
+
+void glGetTexParameterxvOES(GLenum target, GLenum pname, GLfixed *params)
+{
+     getDispatch()->glGetTexParameterxvOES(target, pname, params);
+}
+
+void glLightModelxOES(GLenum pname, GLfixed param)
+{
+     getDispatch()->glLightModelxOES(pname, param);
+}
+
+void glLightModelxvOES(GLenum pname, const GLfixed *params)
+{
+     getDispatch()->glLightModelxvOES(pname, params);
+}
+
+void glLightxOES(GLenum light, GLenum pname, GLfixed param)
+{
+     getDispatch()->glLightxOES(light, pname, param);
+}
+
+void glLightxvOES(GLenum light, GLenum pname, const GLfixed *params)
+{
+     getDispatch()->glLightxvOES(light, pname, params);
+}
+
+void glLineWidthxOES(GLfixed width)
+{
+     getDispatch()->glLineWidthxOES(width);
+}
+
+void glLoadMatrixxOES(const GLfixed *m)
+{
+     getDispatch()->glLoadMatrixxOES(m);
+}
+
+void glMaterialxOES(GLenum face, GLenum pname, GLfixed param)
+{
+     getDispatch()->glMaterialxOES(face, pname, param);
+}
+
+void glMaterialxvOES(GLenum face, GLenum pname, const GLfixed *params)
+{
+     getDispatch()->glMaterialxvOES(face, pname, params);
+}
+
+void glMultMatrixxOES(const GLfixed *m)
+{
+     getDispatch()->glMultMatrixxOES(m);
+}
+
+void glMultiTexCoord4xOES(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q)
+{
+     getDispatch()->glMultiTexCoord4xOES(target, s, t, r, q);
+}
+
+void glNormal3xOES(GLfixed nx, GLfixed ny, GLfixed nz)
+{
+     getDispatch()->glNormal3xOES(nx, ny, nz);
+}
+
+void glOrthoxOES(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
+{
+     getDispatch()->glOrthoxOES(left, right, bottom, top, zNear, zFar);
+}
+
+void glPointParameterxOES(GLenum pname, GLfixed param)
+{
+     getDispatch()->glPointParameterxOES(pname, param);
+}
+
+void glPointParameterxvOES(GLenum pname, const GLfixed *params)
+{
+     getDispatch()->glPointParameterxvOES(pname, params);
+}
+
+void glPointSizexOES(GLfixed size)
+{
+     getDispatch()->glPointSizexOES(size);
+}
+
+void glPolygonOffsetxOES(GLfixed factor, GLfixed units)
+{
+     getDispatch()->glPolygonOffsetxOES(factor, units);
+}
+
+void glRotatexOES(GLfixed angle, GLfixed x, GLfixed y, GLfixed z)
+{
+     getDispatch()->glRotatexOES(angle, x, y, z);
+}
+
+void glSampleCoveragexOES(GLclampx value, GLboolean invert)
+{
+     getDispatch()->glSampleCoveragexOES(value, invert);
+}
+
+void glScalexOES(GLfixed x, GLfixed y, GLfixed z)
+{
+     getDispatch()->glScalexOES(x, y, z);
+}
+
+void glTexEnvxOES(GLenum target, GLenum pname, GLfixed param)
+{
+     getDispatch()->glTexEnvxOES(target, pname, param);
+}
+
+void glTexEnvxvOES(GLenum target, GLenum pname, const GLfixed *params)
+{
+     getDispatch()->glTexEnvxvOES(target, pname, params);
+}
+
+void glTexParameterxOES(GLenum target, GLenum pname, GLfixed param)
+{
+     getDispatch()->glTexParameterxOES(target, pname, param);
+}
+
+void glTexParameterxvOES(GLenum target, GLenum pname, const GLfixed *params)
+{
+     getDispatch()->glTexParameterxvOES(target, pname, params);
+}
+
+void glTranslatexOES(GLfixed x, GLfixed y, GLfixed z)
+{
+     getDispatch()->glTranslatexOES(x, y, z);
+}
+
+GLboolean glIsRenderbufferOES(GLuint renderbuffer)
+{
+     return getDispatch()->glIsRenderbufferOES(renderbuffer);
+}
+
+void glBindRenderbufferOES(GLenum target, GLuint renderbuffer)
+{
+     getDispatch()->glBindRenderbufferOES(target, renderbuffer);
+}
+
+void glDeleteRenderbuffersOES(GLsizei n, const GLuint *renderbuffers)
+{
+     getDispatch()->glDeleteRenderbuffersOES(n, renderbuffers);
+}
+
+void glGenRenderbuffersOES(GLsizei n, GLuint *renderbuffers)
+{
+     getDispatch()->glGenRenderbuffersOES(n, renderbuffers);
+}
+
+void glRenderbufferStorageOES(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+{
+     getDispatch()->glRenderbufferStorageOES(target, internalformat, width, height);
+}
+
+void glGetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint *params)
+{
+     getDispatch()->glGetRenderbufferParameterivOES(target, pname, params);
+}
+
+GLboolean glIsFramebufferOES(GLuint framebuffer)
+{
+     return getDispatch()->glIsFramebufferOES(framebuffer);
+}
+
+void glBindFramebufferOES(GLenum target, GLuint framebuffer)
+{
+     getDispatch()->glBindFramebufferOES(target, framebuffer);
+}
+
+void glDeleteFramebuffersOES(GLsizei n, const GLuint *framebuffers)
+{
+     getDispatch()->glDeleteFramebuffersOES(n, framebuffers);
+}
+
+void glGenFramebuffersOES(GLsizei n, GLuint *framebuffers)
+{
+     getDispatch()->glGenFramebuffersOES(n, framebuffers);
+}
+
+GLenum glCheckFramebufferStatusOES(GLenum target)
+{
+     return getDispatch()->glCheckFramebufferStatusOES(target);
+}
+
+void glFramebufferRenderbufferOES(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
+{
+     getDispatch()->glFramebufferRenderbufferOES(target, attachment, renderbuffertarget, renderbuffer);
+}
+
+void glFramebufferTexture2DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
+{
+     getDispatch()->glFramebufferTexture2DOES(target, attachment, textarget, texture, level);
+}
+
+void glGetFramebufferAttachmentParameterivOES(GLenum target, GLenum attachment, GLenum pname, GLint *params)
+{
+     getDispatch()->glGetFramebufferAttachmentParameterivOES(target, attachment, pname, params);
+}
+
+void glGenerateMipmapOES(GLenum target)
+{
+     getDispatch()->glGenerateMipmapOES(target);
+}
+
+void* glMapBufferOES(GLenum target, GLenum access)
+{
+     return getDispatch()->glMapBufferOES(target, access);
+}
+
+GLboolean glUnmapBufferOES(GLenum target)
+{
+     return getDispatch()->glUnmapBufferOES(target);
+}
+
+void glGetBufferPointervOES(GLenum target, GLenum pname, GLvoid **ptr)
+{
+     getDispatch()->glGetBufferPointervOES(target, pname, ptr);
+}
+
+void glCurrentPaletteMatrixOES(GLuint matrixpaletteindex)
+{
+     getDispatch()->glCurrentPaletteMatrixOES(matrixpaletteindex);
+}
+
+void glLoadPaletteFromModelViewMatrixOES()
+{
+     getDispatch()->glLoadPaletteFromModelViewMatrixOES();
+}
+
+void glMatrixIndexPointerOES(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+     getDispatch()->glMatrixIndexPointerOES(size, type, stride, pointer);
+}
+
+void glWeightPointerOES(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+     getDispatch()->glWeightPointerOES(size, type, stride, pointer);
+}
+
+GLbitfield glQueryMatrixxOES(GLfixed mantissa[16], GLint exponent[16])
+{
+     return getDispatch()->glQueryMatrixxOES(mantissa, exponent);
+}
+
+void glDepthRangefOES(GLclampf zNear, GLclampf zFar)
+{
+     getDispatch()->glDepthRangefOES(zNear, zFar);
+}
+
+void glFrustumfOES(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
+{
+     getDispatch()->glFrustumfOES(left, right, bottom, top, zNear, zFar);
+}
+
+void glOrthofOES(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
+{
+     getDispatch()->glOrthofOES(left, right, bottom, top, zNear, zFar);
+}
+
+void glClipPlanefOES(GLenum plane, const GLfloat *equation)
+{
+     getDispatch()->glClipPlanefOES(plane, equation);
+}
+
+void glGetClipPlanefOES(GLenum pname, GLfloat eqn[4])
+{
+     getDispatch()->glGetClipPlanefOES(pname, eqn);
+}
+
+void glClearDepthfOES(GLclampf depth)
+{
+     getDispatch()->glClearDepthfOES(depth);
+}
+
+void glTexGenfOES(GLenum coord, GLenum pname, GLfloat param)
+{
+     getDispatch()->glTexGenfOES(coord, pname, param);
+}
+
+void glTexGenfvOES(GLenum coord, GLenum pname, const GLfloat *params)
+{
+     getDispatch()->glTexGenfvOES(coord, pname, params);
+}
+
+void glTexGeniOES(GLenum coord, GLenum pname, GLint param)
+{
+     getDispatch()->glTexGeniOES(coord, pname, param);
+}
+
+void glTexGenivOES(GLenum coord, GLenum pname, const GLint *params)
+{
+     getDispatch()->glTexGenivOES(coord, pname, params);
+}
+
+void glTexGenxOES(GLenum coord, GLenum pname, GLfixed param)
+{
+     getDispatch()->glTexGenxOES(coord, pname, param);
+}
+
+void glTexGenxvOES(GLenum coord, GLenum pname, const GLfixed *params)
+{
+     getDispatch()->glTexGenxvOES(coord, pname, params);
+}
+
+void glGetTexGenfvOES(GLenum coord, GLenum pname, GLfloat *params)
+{
+     getDispatch()->glGetTexGenfvOES(coord, pname, params);
+}
+
+void glGetTexGenivOES(GLenum coord, GLenum pname, GLint *params)
+{
+     getDispatch()->glGetTexGenivOES(coord, pname, params);
+}
+
+void glGetTexGenxvOES(GLenum coord, GLenum pname, GLfixed *params)
+{
+     getDispatch()->glGetTexGenxvOES(coord, pname, params);
+}
+
+void glBindVertexArrayOES(GLuint array)
+{
+     getDispatch()->glBindVertexArrayOES(array);
+}
+
+void glDeleteVertexArraysOES(GLsizei n, const GLuint *arrays)
+{
+     getDispatch()->glDeleteVertexArraysOES(n, arrays);
+}
+
+void glGenVertexArraysOES(GLsizei n, GLuint *arrays)
+{
+     getDispatch()->glGenVertexArraysOES(n, arrays);
+}
+
+GLboolean glIsVertexArrayOES(GLuint array)
+{
+     return getDispatch()->glIsVertexArrayOES(array);
+}
+
+void glDiscardFramebufferEXT(GLenum target, GLsizei numAttachments, const GLenum *attachments)
+{
+     getDispatch()->glDiscardFramebufferEXT(target, numAttachments, attachments);
+}
+
+void glMultiDrawArraysEXT(GLenum mode, GLint *first, GLsizei *count, GLsizei primcount)
+{
+     getDispatch()->glMultiDrawArraysEXT(mode, first, count, primcount);
+}
+
+void glMultiDrawElementsEXT(GLenum mode, const GLsizei *count, GLenum type, const GLvoid **indices, GLsizei primcount)
+{
+     getDispatch()->glMultiDrawElementsEXT(mode, count, type, indices, primcount);
+}
+
+void glClipPlanefIMG(GLenum p, const GLfloat *eqn)
+{
+     getDispatch()->glClipPlanefIMG(p, eqn);
+}
+
+void glClipPlanexIMG(GLenum p, const GLfixed *eqn)
+{
+     getDispatch()->glClipPlanexIMG(p, eqn);
+}
+
+void glRenderbufferStorageMultisampleIMG(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
+{
+     getDispatch()->glRenderbufferStorageMultisampleIMG(target, samples, internalformat, width, height);
+}
+
+void glFramebufferTexture2DMultisampleIMG(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples)
+{
+     getDispatch()->glFramebufferTexture2DMultisampleIMG(target, attachment, textarget, texture, level, samples);
+}
+
+void glDeleteFencesNV(GLsizei n, const GLuint *fences)
+{
+     getDispatch()->glDeleteFencesNV(n, fences);
+}
+
+void glGenFencesNV(GLsizei n, GLuint *fences)
+{
+     getDispatch()->glGenFencesNV(n, fences);
+}
+
+GLboolean glIsFenceNV(GLuint fence)
+{
+     return getDispatch()->glIsFenceNV(fence);
+}
+
+GLboolean glTestFenceNV(GLuint fence)
+{
+     return getDispatch()->glTestFenceNV(fence);
+}
+
+void glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
+{
+     getDispatch()->glGetFenceivNV(fence, pname, params);
+}
+
+void glFinishFenceNV(GLuint fence)
+{
+     getDispatch()->glFinishFenceNV(fence);
+}
+
+void glSetFenceNV(GLuint fence, GLenum condition)
+{
+     getDispatch()->glSetFenceNV(fence, condition);
+}
+
+void glGetDriverControlsQCOM(GLint *num, GLsizei size, GLuint *driverControls)
+{
+     getDispatch()->glGetDriverControlsQCOM(num, size, driverControls);
+}
+
+void glGetDriverControlStringQCOM(GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString)
+{
+     getDispatch()->glGetDriverControlStringQCOM(driverControl, bufSize, length, driverControlString);
+}
+
+void glEnableDriverControlQCOM(GLuint driverControl)
+{
+     getDispatch()->glEnableDriverControlQCOM(driverControl);
+}
+
+void glDisableDriverControlQCOM(GLuint driverControl)
+{
+     getDispatch()->glDisableDriverControlQCOM(driverControl);
+}
+
+void glExtGetTexturesQCOM(GLuint *textures, GLint maxTextures, GLint *numTextures)
+{
+     getDispatch()->glExtGetTexturesQCOM(textures, maxTextures, numTextures);
+}
+
+void glExtGetBuffersQCOM(GLuint *buffers, GLint maxBuffers, GLint *numBuffers)
+{
+     getDispatch()->glExtGetBuffersQCOM(buffers, maxBuffers, numBuffers);
+}
+
+void glExtGetRenderbuffersQCOM(GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers)
+{
+     getDispatch()->glExtGetRenderbuffersQCOM(renderbuffers, maxRenderbuffers, numRenderbuffers);
+}
+
+void glExtGetFramebuffersQCOM(GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers)
+{
+     getDispatch()->glExtGetFramebuffersQCOM(framebuffers, maxFramebuffers, numFramebuffers);
+}
+
+void glExtGetTexLevelParameterivQCOM(GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params)
+{
+     getDispatch()->glExtGetTexLevelParameterivQCOM(texture, face, level, pname, params);
+}
+
+void glExtTexObjectStateOverrideiQCOM(GLenum target, GLenum pname, GLint param)
+{
+     getDispatch()->glExtTexObjectStateOverrideiQCOM(target, pname, param);
+}
+
+void glExtGetTexSubImageQCOM(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid *texels)
+{
+     getDispatch()->glExtGetTexSubImageQCOM(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, texels);
+}
+
+void glExtGetBufferPointervQCOM(GLenum target, GLvoid **params)
+{
+     getDispatch()->glExtGetBufferPointervQCOM(target, params);
+}
+
+void glExtGetShadersQCOM(GLuint *shaders, GLint maxShaders, GLint *numShaders)
+{
+     getDispatch()->glExtGetShadersQCOM(shaders, maxShaders, numShaders);
+}
+
+void glExtGetProgramsQCOM(GLuint *programs, GLint maxPrograms, GLint *numPrograms)
+{
+     getDispatch()->glExtGetProgramsQCOM(programs, maxPrograms, numPrograms);
+}
+
+GLboolean glExtIsProgramBinaryQCOM(GLuint program)
+{
+     return getDispatch()->glExtIsProgramBinaryQCOM(program);
+}
+
+void glExtGetProgramBinarySourceQCOM(GLuint program, GLenum shadertype, GLchar *source, GLint *length)
+{
+     getDispatch()->glExtGetProgramBinarySourceQCOM(program, shadertype, source, length);
+}
+
+void glStartTilingQCOM(GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask)
+{
+     getDispatch()->glStartTilingQCOM(x, y, width, height, preserveMask);
+}
+
+void glEndTilingQCOM(GLbitfield preserveMask)
+{
+     getDispatch()->glEndTilingQCOM(preserveMask);
+}
+
diff --git a/opengl/tests/gles_android_wrapper/gles_dispatch.cpp b/opengl/tests/gles_android_wrapper/gles_dispatch.cpp
new file mode 100644
index 0000000..0a17624
--- /dev/null
+++ b/opengl/tests/gles_android_wrapper/gles_dispatch.cpp
@@ -0,0 +1,298 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#include "gles_dispatch.h"
+#include <stdio.h>
+#include <dlfcn.h>
+
+gles_dispatch *create_gles_dispatch(void *gles_android)
+{
+        gles_dispatch *disp = new gles_dispatch;
+
+    void *ptr;
+    ptr = dlsym(gles_android,"glAlphaFunc"); disp->set_glAlphaFunc((glAlphaFunc_t)ptr);
+    ptr = dlsym(gles_android,"glClearColor"); disp->set_glClearColor((glClearColor_t)ptr);
+    ptr = dlsym(gles_android,"glClearDepthf"); disp->set_glClearDepthf((glClearDepthf_t)ptr);
+    ptr = dlsym(gles_android,"glClipPlanef"); disp->set_glClipPlanef((glClipPlanef_t)ptr);
+    ptr = dlsym(gles_android,"glColor4f"); disp->set_glColor4f((glColor4f_t)ptr);
+    ptr = dlsym(gles_android,"glDepthRangef"); disp->set_glDepthRangef((glDepthRangef_t)ptr);
+    ptr = dlsym(gles_android,"glFogf"); disp->set_glFogf((glFogf_t)ptr);
+    ptr = dlsym(gles_android,"glFogfv"); disp->set_glFogfv((glFogfv_t)ptr);
+    ptr = dlsym(gles_android,"glFrustumf"); disp->set_glFrustumf((glFrustumf_t)ptr);
+    ptr = dlsym(gles_android,"glGetClipPlanef"); disp->set_glGetClipPlanef((glGetClipPlanef_t)ptr);
+    ptr = dlsym(gles_android,"glGetFloatv"); disp->set_glGetFloatv((glGetFloatv_t)ptr);
+    ptr = dlsym(gles_android,"glGetLightfv"); disp->set_glGetLightfv((glGetLightfv_t)ptr);
+    ptr = dlsym(gles_android,"glGetMaterialfv"); disp->set_glGetMaterialfv((glGetMaterialfv_t)ptr);
+    ptr = dlsym(gles_android,"glGetTexEnvfv"); disp->set_glGetTexEnvfv((glGetTexEnvfv_t)ptr);
+    ptr = dlsym(gles_android,"glGetTexParameterfv"); disp->set_glGetTexParameterfv((glGetTexParameterfv_t)ptr);
+    ptr = dlsym(gles_android,"glLightModelf"); disp->set_glLightModelf((glLightModelf_t)ptr);
+    ptr = dlsym(gles_android,"glLightModelfv"); disp->set_glLightModelfv((glLightModelfv_t)ptr);
+    ptr = dlsym(gles_android,"glLightf"); disp->set_glLightf((glLightf_t)ptr);
+    ptr = dlsym(gles_android,"glLightfv"); disp->set_glLightfv((glLightfv_t)ptr);
+    ptr = dlsym(gles_android,"glLineWidth"); disp->set_glLineWidth((glLineWidth_t)ptr);
+    ptr = dlsym(gles_android,"glLoadMatrixf"); disp->set_glLoadMatrixf((glLoadMatrixf_t)ptr);
+    ptr = dlsym(gles_android,"glMaterialf"); disp->set_glMaterialf((glMaterialf_t)ptr);
+    ptr = dlsym(gles_android,"glMaterialfv"); disp->set_glMaterialfv((glMaterialfv_t)ptr);
+    ptr = dlsym(gles_android,"glMultMatrixf"); disp->set_glMultMatrixf((glMultMatrixf_t)ptr);
+    ptr = dlsym(gles_android,"glMultiTexCoord4f"); disp->set_glMultiTexCoord4f((glMultiTexCoord4f_t)ptr);
+    ptr = dlsym(gles_android,"glNormal3f"); disp->set_glNormal3f((glNormal3f_t)ptr);
+    ptr = dlsym(gles_android,"glOrthof"); disp->set_glOrthof((glOrthof_t)ptr);
+    ptr = dlsym(gles_android,"glPointParameterf"); disp->set_glPointParameterf((glPointParameterf_t)ptr);
+    ptr = dlsym(gles_android,"glPointParameterfv"); disp->set_glPointParameterfv((glPointParameterfv_t)ptr);
+    ptr = dlsym(gles_android,"glPointSize"); disp->set_glPointSize((glPointSize_t)ptr);
+    ptr = dlsym(gles_android,"glPolygonOffset"); disp->set_glPolygonOffset((glPolygonOffset_t)ptr);
+    ptr = dlsym(gles_android,"glRotatef"); disp->set_glRotatef((glRotatef_t)ptr);
+    ptr = dlsym(gles_android,"glScalef"); disp->set_glScalef((glScalef_t)ptr);
+    ptr = dlsym(gles_android,"glTexEnvf"); disp->set_glTexEnvf((glTexEnvf_t)ptr);
+    ptr = dlsym(gles_android,"glTexEnvfv"); disp->set_glTexEnvfv((glTexEnvfv_t)ptr);
+    ptr = dlsym(gles_android,"glTexParameterf"); disp->set_glTexParameterf((glTexParameterf_t)ptr);
+    ptr = dlsym(gles_android,"glTexParameterfv"); disp->set_glTexParameterfv((glTexParameterfv_t)ptr);
+    ptr = dlsym(gles_android,"glTranslatef"); disp->set_glTranslatef((glTranslatef_t)ptr);
+    ptr = dlsym(gles_android,"glActiveTexture"); disp->set_glActiveTexture((glActiveTexture_t)ptr);
+    ptr = dlsym(gles_android,"glAlphaFuncx"); disp->set_glAlphaFuncx((glAlphaFuncx_t)ptr);
+    ptr = dlsym(gles_android,"glBindBuffer"); disp->set_glBindBuffer((glBindBuffer_t)ptr);
+    ptr = dlsym(gles_android,"glBindTexture"); disp->set_glBindTexture((glBindTexture_t)ptr);
+    ptr = dlsym(gles_android,"glBlendFunc"); disp->set_glBlendFunc((glBlendFunc_t)ptr);
+    ptr = dlsym(gles_android,"glBufferData"); disp->set_glBufferData((glBufferData_t)ptr);
+    ptr = dlsym(gles_android,"glBufferSubData"); disp->set_glBufferSubData((glBufferSubData_t)ptr);
+    ptr = dlsym(gles_android,"glClear"); disp->set_glClear((glClear_t)ptr);
+    ptr = dlsym(gles_android,"glClearColorx"); disp->set_glClearColorx((glClearColorx_t)ptr);
+    ptr = dlsym(gles_android,"glClearDepthx"); disp->set_glClearDepthx((glClearDepthx_t)ptr);
+    ptr = dlsym(gles_android,"glClearStencil"); disp->set_glClearStencil((glClearStencil_t)ptr);
+    ptr = dlsym(gles_android,"glClientActiveTexture"); disp->set_glClientActiveTexture((glClientActiveTexture_t)ptr);
+    ptr = dlsym(gles_android,"glClipPlanex"); disp->set_glClipPlanex((glClipPlanex_t)ptr);
+    ptr = dlsym(gles_android,"glColor4ub"); disp->set_glColor4ub((glColor4ub_t)ptr);
+    ptr = dlsym(gles_android,"glColor4x"); disp->set_glColor4x((glColor4x_t)ptr);
+    ptr = dlsym(gles_android,"glColorMask"); disp->set_glColorMask((glColorMask_t)ptr);
+    ptr = dlsym(gles_android,"glColorPointer"); disp->set_glColorPointer((glColorPointer_t)ptr);
+    ptr = dlsym(gles_android,"glCompressedTexImage2D"); disp->set_glCompressedTexImage2D((glCompressedTexImage2D_t)ptr);
+    ptr = dlsym(gles_android,"glCompressedTexSubImage2D"); disp->set_glCompressedTexSubImage2D((glCompressedTexSubImage2D_t)ptr);
+    ptr = dlsym(gles_android,"glCopyTexImage2D"); disp->set_glCopyTexImage2D((glCopyTexImage2D_t)ptr);
+    ptr = dlsym(gles_android,"glCopyTexSubImage2D"); disp->set_glCopyTexSubImage2D((glCopyTexSubImage2D_t)ptr);
+    ptr = dlsym(gles_android,"glCullFace"); disp->set_glCullFace((glCullFace_t)ptr);
+    ptr = dlsym(gles_android,"glDeleteBuffers"); disp->set_glDeleteBuffers((glDeleteBuffers_t)ptr);
+    ptr = dlsym(gles_android,"glDeleteTextures"); disp->set_glDeleteTextures((glDeleteTextures_t)ptr);
+    ptr = dlsym(gles_android,"glDepthFunc"); disp->set_glDepthFunc((glDepthFunc_t)ptr);
+    ptr = dlsym(gles_android,"glDepthMask"); disp->set_glDepthMask((glDepthMask_t)ptr);
+    ptr = dlsym(gles_android,"glDepthRangex"); disp->set_glDepthRangex((glDepthRangex_t)ptr);
+    ptr = dlsym(gles_android,"glDisable"); disp->set_glDisable((glDisable_t)ptr);
+    ptr = dlsym(gles_android,"glDisableClientState"); disp->set_glDisableClientState((glDisableClientState_t)ptr);
+    ptr = dlsym(gles_android,"glDrawArrays"); disp->set_glDrawArrays((glDrawArrays_t)ptr);
+    ptr = dlsym(gles_android,"glDrawElements"); disp->set_glDrawElements((glDrawElements_t)ptr);
+    ptr = dlsym(gles_android,"glEnable"); disp->set_glEnable((glEnable_t)ptr);
+    ptr = dlsym(gles_android,"glEnableClientState"); disp->set_glEnableClientState((glEnableClientState_t)ptr);
+    ptr = dlsym(gles_android,"glFinish"); disp->set_glFinish((glFinish_t)ptr);
+    ptr = dlsym(gles_android,"glFlush"); disp->set_glFlush((glFlush_t)ptr);
+    ptr = dlsym(gles_android,"glFogx"); disp->set_glFogx((glFogx_t)ptr);
+    ptr = dlsym(gles_android,"glFogxv"); disp->set_glFogxv((glFogxv_t)ptr);
+    ptr = dlsym(gles_android,"glFrontFace"); disp->set_glFrontFace((glFrontFace_t)ptr);
+    ptr = dlsym(gles_android,"glFrustumx"); disp->set_glFrustumx((glFrustumx_t)ptr);
+    ptr = dlsym(gles_android,"glGetBooleanv"); disp->set_glGetBooleanv((glGetBooleanv_t)ptr);
+    ptr = dlsym(gles_android,"glGetBufferParameteriv"); disp->set_glGetBufferParameteriv((glGetBufferParameteriv_t)ptr);
+    ptr = dlsym(gles_android,"glGetClipPlanex"); disp->set_glGetClipPlanex((glGetClipPlanex_t)ptr);
+    ptr = dlsym(gles_android,"glGenBuffers"); disp->set_glGenBuffers((glGenBuffers_t)ptr);
+    ptr = dlsym(gles_android,"glGenTextures"); disp->set_glGenTextures((glGenTextures_t)ptr);
+    ptr = dlsym(gles_android,"glGetError"); disp->set_glGetError((glGetError_t)ptr);
+    ptr = dlsym(gles_android,"glGetFixedv"); disp->set_glGetFixedv((glGetFixedv_t)ptr);
+    ptr = dlsym(gles_android,"glGetIntegerv"); disp->set_glGetIntegerv((glGetIntegerv_t)ptr);
+    ptr = dlsym(gles_android,"glGetLightxv"); disp->set_glGetLightxv((glGetLightxv_t)ptr);
+    ptr = dlsym(gles_android,"glGetMaterialxv"); disp->set_glGetMaterialxv((glGetMaterialxv_t)ptr);
+    ptr = dlsym(gles_android,"glGetPointerv"); disp->set_glGetPointerv((glGetPointerv_t)ptr);
+    ptr = dlsym(gles_android,"glGetString"); disp->set_glGetString((glGetString_t)ptr);
+    ptr = dlsym(gles_android,"glGetTexEnviv"); disp->set_glGetTexEnviv((glGetTexEnviv_t)ptr);
+    ptr = dlsym(gles_android,"glGetTexEnvxv"); disp->set_glGetTexEnvxv((glGetTexEnvxv_t)ptr);
+    ptr = dlsym(gles_android,"glGetTexParameteriv"); disp->set_glGetTexParameteriv((glGetTexParameteriv_t)ptr);
+    ptr = dlsym(gles_android,"glGetTexParameterxv"); disp->set_glGetTexParameterxv((glGetTexParameterxv_t)ptr);
+    ptr = dlsym(gles_android,"glHint"); disp->set_glHint((glHint_t)ptr);
+    ptr = dlsym(gles_android,"glIsBuffer"); disp->set_glIsBuffer((glIsBuffer_t)ptr);
+    ptr = dlsym(gles_android,"glIsEnabled"); disp->set_glIsEnabled((glIsEnabled_t)ptr);
+    ptr = dlsym(gles_android,"glIsTexture"); disp->set_glIsTexture((glIsTexture_t)ptr);
+    ptr = dlsym(gles_android,"glLightModelx"); disp->set_glLightModelx((glLightModelx_t)ptr);
+    ptr = dlsym(gles_android,"glLightModelxv"); disp->set_glLightModelxv((glLightModelxv_t)ptr);
+    ptr = dlsym(gles_android,"glLightx"); disp->set_glLightx((glLightx_t)ptr);
+    ptr = dlsym(gles_android,"glLightxv"); disp->set_glLightxv((glLightxv_t)ptr);
+    ptr = dlsym(gles_android,"glLineWidthx"); disp->set_glLineWidthx((glLineWidthx_t)ptr);
+    ptr = dlsym(gles_android,"glLoadIdentity"); disp->set_glLoadIdentity((glLoadIdentity_t)ptr);
+    ptr = dlsym(gles_android,"glLoadMatrixx"); disp->set_glLoadMatrixx((glLoadMatrixx_t)ptr);
+    ptr = dlsym(gles_android,"glLogicOp"); disp->set_glLogicOp((glLogicOp_t)ptr);
+    ptr = dlsym(gles_android,"glMaterialx"); disp->set_glMaterialx((glMaterialx_t)ptr);
+    ptr = dlsym(gles_android,"glMaterialxv"); disp->set_glMaterialxv((glMaterialxv_t)ptr);
+    ptr = dlsym(gles_android,"glMatrixMode"); disp->set_glMatrixMode((glMatrixMode_t)ptr);
+    ptr = dlsym(gles_android,"glMultMatrixx"); disp->set_glMultMatrixx((glMultMatrixx_t)ptr);
+    ptr = dlsym(gles_android,"glMultiTexCoord4x"); disp->set_glMultiTexCoord4x((glMultiTexCoord4x_t)ptr);
+    ptr = dlsym(gles_android,"glNormal3x"); disp->set_glNormal3x((glNormal3x_t)ptr);
+    ptr = dlsym(gles_android,"glNormalPointer"); disp->set_glNormalPointer((glNormalPointer_t)ptr);
+    ptr = dlsym(gles_android,"glOrthox"); disp->set_glOrthox((glOrthox_t)ptr);
+    ptr = dlsym(gles_android,"glPixelStorei"); disp->set_glPixelStorei((glPixelStorei_t)ptr);
+    ptr = dlsym(gles_android,"glPointParameterx"); disp->set_glPointParameterx((glPointParameterx_t)ptr);
+    ptr = dlsym(gles_android,"glPointParameterxv"); disp->set_glPointParameterxv((glPointParameterxv_t)ptr);
+    ptr = dlsym(gles_android,"glPointSizex"); disp->set_glPointSizex((glPointSizex_t)ptr);
+    ptr = dlsym(gles_android,"glPolygonOffsetx"); disp->set_glPolygonOffsetx((glPolygonOffsetx_t)ptr);
+    ptr = dlsym(gles_android,"glPopMatrix"); disp->set_glPopMatrix((glPopMatrix_t)ptr);
+    ptr = dlsym(gles_android,"glPushMatrix"); disp->set_glPushMatrix((glPushMatrix_t)ptr);
+    ptr = dlsym(gles_android,"glReadPixels"); disp->set_glReadPixels((glReadPixels_t)ptr);
+    ptr = dlsym(gles_android,"glRotatex"); disp->set_glRotatex((glRotatex_t)ptr);
+    ptr = dlsym(gles_android,"glSampleCoverage"); disp->set_glSampleCoverage((glSampleCoverage_t)ptr);
+    ptr = dlsym(gles_android,"glSampleCoveragex"); disp->set_glSampleCoveragex((glSampleCoveragex_t)ptr);
+    ptr = dlsym(gles_android,"glScalex"); disp->set_glScalex((glScalex_t)ptr);
+    ptr = dlsym(gles_android,"glScissor"); disp->set_glScissor((glScissor_t)ptr);
+    ptr = dlsym(gles_android,"glShadeModel"); disp->set_glShadeModel((glShadeModel_t)ptr);
+    ptr = dlsym(gles_android,"glStencilFunc"); disp->set_glStencilFunc((glStencilFunc_t)ptr);
+    ptr = dlsym(gles_android,"glStencilMask"); disp->set_glStencilMask((glStencilMask_t)ptr);
+    ptr = dlsym(gles_android,"glStencilOp"); disp->set_glStencilOp((glStencilOp_t)ptr);
+    ptr = dlsym(gles_android,"glTexCoordPointer"); disp->set_glTexCoordPointer((glTexCoordPointer_t)ptr);
+    ptr = dlsym(gles_android,"glTexEnvi"); disp->set_glTexEnvi((glTexEnvi_t)ptr);
+    ptr = dlsym(gles_android,"glTexEnvx"); disp->set_glTexEnvx((glTexEnvx_t)ptr);
+    ptr = dlsym(gles_android,"glTexEnviv"); disp->set_glTexEnviv((glTexEnviv_t)ptr);
+    ptr = dlsym(gles_android,"glTexEnvxv"); disp->set_glTexEnvxv((glTexEnvxv_t)ptr);
+    ptr = dlsym(gles_android,"glTexImage2D"); disp->set_glTexImage2D((glTexImage2D_t)ptr);
+    ptr = dlsym(gles_android,"glTexParameteri"); disp->set_glTexParameteri((glTexParameteri_t)ptr);
+    ptr = dlsym(gles_android,"glTexParameterx"); disp->set_glTexParameterx((glTexParameterx_t)ptr);
+    ptr = dlsym(gles_android,"glTexParameteriv"); disp->set_glTexParameteriv((glTexParameteriv_t)ptr);
+    ptr = dlsym(gles_android,"glTexParameterxv"); disp->set_glTexParameterxv((glTexParameterxv_t)ptr);
+    ptr = dlsym(gles_android,"glTexSubImage2D"); disp->set_glTexSubImage2D((glTexSubImage2D_t)ptr);
+    ptr = dlsym(gles_android,"glTranslatex"); disp->set_glTranslatex((glTranslatex_t)ptr);
+    ptr = dlsym(gles_android,"glVertexPointer"); disp->set_glVertexPointer((glVertexPointer_t)ptr);
+    ptr = dlsym(gles_android,"glViewport"); disp->set_glViewport((glViewport_t)ptr);
+    ptr = dlsym(gles_android,"glPointSizePointerOES"); disp->set_glPointSizePointerOES((glPointSizePointerOES_t)ptr);
+    ptr = dlsym(gles_android,"glBlendEquationSeparateOES"); disp->set_glBlendEquationSeparateOES((glBlendEquationSeparateOES_t)ptr);
+    ptr = dlsym(gles_android,"glBlendFuncSeparateOES"); disp->set_glBlendFuncSeparateOES((glBlendFuncSeparateOES_t)ptr);
+    ptr = dlsym(gles_android,"glBlendEquationOES"); disp->set_glBlendEquationOES((glBlendEquationOES_t)ptr);
+    ptr = dlsym(gles_android,"glDrawTexsOES"); disp->set_glDrawTexsOES((glDrawTexsOES_t)ptr);
+    ptr = dlsym(gles_android,"glDrawTexiOES"); disp->set_glDrawTexiOES((glDrawTexiOES_t)ptr);
+    ptr = dlsym(gles_android,"glDrawTexxOES"); disp->set_glDrawTexxOES((glDrawTexxOES_t)ptr);
+    ptr = dlsym(gles_android,"glDrawTexsvOES"); disp->set_glDrawTexsvOES((glDrawTexsvOES_t)ptr);
+    ptr = dlsym(gles_android,"glDrawTexivOES"); disp->set_glDrawTexivOES((glDrawTexivOES_t)ptr);
+    ptr = dlsym(gles_android,"glDrawTexxvOES"); disp->set_glDrawTexxvOES((glDrawTexxvOES_t)ptr);
+    ptr = dlsym(gles_android,"glDrawTexfOES"); disp->set_glDrawTexfOES((glDrawTexfOES_t)ptr);
+    ptr = dlsym(gles_android,"glDrawTexfvOES"); disp->set_glDrawTexfvOES((glDrawTexfvOES_t)ptr);
+    ptr = dlsym(gles_android,"glEGLImageTargetTexture2DOES"); disp->set_glEGLImageTargetTexture2DOES((glEGLImageTargetTexture2DOES_t)ptr);
+    ptr = dlsym(gles_android,"glEGLImageTargetRenderbufferStorageOES"); disp->set_glEGLImageTargetRenderbufferStorageOES((glEGLImageTargetRenderbufferStorageOES_t)ptr);
+    ptr = dlsym(gles_android,"glAlphaFuncxOES"); disp->set_glAlphaFuncxOES((glAlphaFuncxOES_t)ptr);
+    ptr = dlsym(gles_android,"glClearColorxOES"); disp->set_glClearColorxOES((glClearColorxOES_t)ptr);
+    ptr = dlsym(gles_android,"glClearDepthxOES"); disp->set_glClearDepthxOES((glClearDepthxOES_t)ptr);
+    ptr = dlsym(gles_android,"glClipPlanexOES"); disp->set_glClipPlanexOES((glClipPlanexOES_t)ptr);
+    ptr = dlsym(gles_android,"glColor4xOES"); disp->set_glColor4xOES((glColor4xOES_t)ptr);
+    ptr = dlsym(gles_android,"glDepthRangexOES"); disp->set_glDepthRangexOES((glDepthRangexOES_t)ptr);
+    ptr = dlsym(gles_android,"glFogxOES"); disp->set_glFogxOES((glFogxOES_t)ptr);
+    ptr = dlsym(gles_android,"glFogxvOES"); disp->set_glFogxvOES((glFogxvOES_t)ptr);
+    ptr = dlsym(gles_android,"glFrustumxOES"); disp->set_glFrustumxOES((glFrustumxOES_t)ptr);
+    ptr = dlsym(gles_android,"glGetClipPlanexOES"); disp->set_glGetClipPlanexOES((glGetClipPlanexOES_t)ptr);
+    ptr = dlsym(gles_android,"glGetFixedvOES"); disp->set_glGetFixedvOES((glGetFixedvOES_t)ptr);
+    ptr = dlsym(gles_android,"glGetLightxvOES"); disp->set_glGetLightxvOES((glGetLightxvOES_t)ptr);
+    ptr = dlsym(gles_android,"glGetMaterialxvOES"); disp->set_glGetMaterialxvOES((glGetMaterialxvOES_t)ptr);
+    ptr = dlsym(gles_android,"glGetTexEnvxvOES"); disp->set_glGetTexEnvxvOES((glGetTexEnvxvOES_t)ptr);
+    ptr = dlsym(gles_android,"glGetTexParameterxvOES"); disp->set_glGetTexParameterxvOES((glGetTexParameterxvOES_t)ptr);
+    ptr = dlsym(gles_android,"glLightModelxOES"); disp->set_glLightModelxOES((glLightModelxOES_t)ptr);
+    ptr = dlsym(gles_android,"glLightModelxvOES"); disp->set_glLightModelxvOES((glLightModelxvOES_t)ptr);
+    ptr = dlsym(gles_android,"glLightxOES"); disp->set_glLightxOES((glLightxOES_t)ptr);
+    ptr = dlsym(gles_android,"glLightxvOES"); disp->set_glLightxvOES((glLightxvOES_t)ptr);
+    ptr = dlsym(gles_android,"glLineWidthxOES"); disp->set_glLineWidthxOES((glLineWidthxOES_t)ptr);
+    ptr = dlsym(gles_android,"glLoadMatrixxOES"); disp->set_glLoadMatrixxOES((glLoadMatrixxOES_t)ptr);
+    ptr = dlsym(gles_android,"glMaterialxOES"); disp->set_glMaterialxOES((glMaterialxOES_t)ptr);
+    ptr = dlsym(gles_android,"glMaterialxvOES"); disp->set_glMaterialxvOES((glMaterialxvOES_t)ptr);
+    ptr = dlsym(gles_android,"glMultMatrixxOES"); disp->set_glMultMatrixxOES((glMultMatrixxOES_t)ptr);
+    ptr = dlsym(gles_android,"glMultiTexCoord4xOES"); disp->set_glMultiTexCoord4xOES((glMultiTexCoord4xOES_t)ptr);
+    ptr = dlsym(gles_android,"glNormal3xOES"); disp->set_glNormal3xOES((glNormal3xOES_t)ptr);
+    ptr = dlsym(gles_android,"glOrthoxOES"); disp->set_glOrthoxOES((glOrthoxOES_t)ptr);
+    ptr = dlsym(gles_android,"glPointParameterxOES"); disp->set_glPointParameterxOES((glPointParameterxOES_t)ptr);
+    ptr = dlsym(gles_android,"glPointParameterxvOES"); disp->set_glPointParameterxvOES((glPointParameterxvOES_t)ptr);
+    ptr = dlsym(gles_android,"glPointSizexOES"); disp->set_glPointSizexOES((glPointSizexOES_t)ptr);
+    ptr = dlsym(gles_android,"glPolygonOffsetxOES"); disp->set_glPolygonOffsetxOES((glPolygonOffsetxOES_t)ptr);
+    ptr = dlsym(gles_android,"glRotatexOES"); disp->set_glRotatexOES((glRotatexOES_t)ptr);
+    ptr = dlsym(gles_android,"glSampleCoveragexOES"); disp->set_glSampleCoveragexOES((glSampleCoveragexOES_t)ptr);
+    ptr = dlsym(gles_android,"glScalexOES"); disp->set_glScalexOES((glScalexOES_t)ptr);
+    ptr = dlsym(gles_android,"glTexEnvxOES"); disp->set_glTexEnvxOES((glTexEnvxOES_t)ptr);
+    ptr = dlsym(gles_android,"glTexEnvxvOES"); disp->set_glTexEnvxvOES((glTexEnvxvOES_t)ptr);
+    ptr = dlsym(gles_android,"glTexParameterxOES"); disp->set_glTexParameterxOES((glTexParameterxOES_t)ptr);
+    ptr = dlsym(gles_android,"glTexParameterxvOES"); disp->set_glTexParameterxvOES((glTexParameterxvOES_t)ptr);
+    ptr = dlsym(gles_android,"glTranslatexOES"); disp->set_glTranslatexOES((glTranslatexOES_t)ptr);
+    ptr = dlsym(gles_android,"glIsRenderbufferOES"); disp->set_glIsRenderbufferOES((glIsRenderbufferOES_t)ptr);
+    ptr = dlsym(gles_android,"glBindRenderbufferOES"); disp->set_glBindRenderbufferOES((glBindRenderbufferOES_t)ptr);
+    ptr = dlsym(gles_android,"glDeleteRenderbuffersOES"); disp->set_glDeleteRenderbuffersOES((glDeleteRenderbuffersOES_t)ptr);
+    ptr = dlsym(gles_android,"glGenRenderbuffersOES"); disp->set_glGenRenderbuffersOES((glGenRenderbuffersOES_t)ptr);
+    ptr = dlsym(gles_android,"glRenderbufferStorageOES"); disp->set_glRenderbufferStorageOES((glRenderbufferStorageOES_t)ptr);
+    ptr = dlsym(gles_android,"glGetRenderbufferParameterivOES"); disp->set_glGetRenderbufferParameterivOES((glGetRenderbufferParameterivOES_t)ptr);
+    ptr = dlsym(gles_android,"glIsFramebufferOES"); disp->set_glIsFramebufferOES((glIsFramebufferOES_t)ptr);
+    ptr = dlsym(gles_android,"glBindFramebufferOES"); disp->set_glBindFramebufferOES((glBindFramebufferOES_t)ptr);
+    ptr = dlsym(gles_android,"glDeleteFramebuffersOES"); disp->set_glDeleteFramebuffersOES((glDeleteFramebuffersOES_t)ptr);
+    ptr = dlsym(gles_android,"glGenFramebuffersOES"); disp->set_glGenFramebuffersOES((glGenFramebuffersOES_t)ptr);
+    ptr = dlsym(gles_android,"glCheckFramebufferStatusOES"); disp->set_glCheckFramebufferStatusOES((glCheckFramebufferStatusOES_t)ptr);
+    ptr = dlsym(gles_android,"glFramebufferRenderbufferOES"); disp->set_glFramebufferRenderbufferOES((glFramebufferRenderbufferOES_t)ptr);
+    ptr = dlsym(gles_android,"glFramebufferTexture2DOES"); disp->set_glFramebufferTexture2DOES((glFramebufferTexture2DOES_t)ptr);
+    ptr = dlsym(gles_android,"glGetFramebufferAttachmentParameterivOES"); disp->set_glGetFramebufferAttachmentParameterivOES((glGetFramebufferAttachmentParameterivOES_t)ptr);
+    ptr = dlsym(gles_android,"glGenerateMipmapOES"); disp->set_glGenerateMipmapOES((glGenerateMipmapOES_t)ptr);
+    ptr = dlsym(gles_android,"glMapBufferOES"); disp->set_glMapBufferOES((glMapBufferOES_t)ptr);
+    ptr = dlsym(gles_android,"glUnmapBufferOES"); disp->set_glUnmapBufferOES((glUnmapBufferOES_t)ptr);
+    ptr = dlsym(gles_android,"glGetBufferPointervOES"); disp->set_glGetBufferPointervOES((glGetBufferPointervOES_t)ptr);
+    ptr = dlsym(gles_android,"glCurrentPaletteMatrixOES"); disp->set_glCurrentPaletteMatrixOES((glCurrentPaletteMatrixOES_t)ptr);
+    ptr = dlsym(gles_android,"glLoadPaletteFromModelViewMatrixOES"); disp->set_glLoadPaletteFromModelViewMatrixOES((glLoadPaletteFromModelViewMatrixOES_t)ptr);
+    ptr = dlsym(gles_android,"glMatrixIndexPointerOES"); disp->set_glMatrixIndexPointerOES((glMatrixIndexPointerOES_t)ptr);
+    ptr = dlsym(gles_android,"glWeightPointerOES"); disp->set_glWeightPointerOES((glWeightPointerOES_t)ptr);
+    ptr = dlsym(gles_android,"glQueryMatrixxOES"); disp->set_glQueryMatrixxOES((glQueryMatrixxOES_t)ptr);
+    ptr = dlsym(gles_android,"glDepthRangefOES"); disp->set_glDepthRangefOES((glDepthRangefOES_t)ptr);
+    ptr = dlsym(gles_android,"glFrustumfOES"); disp->set_glFrustumfOES((glFrustumfOES_t)ptr);
+    ptr = dlsym(gles_android,"glOrthofOES"); disp->set_glOrthofOES((glOrthofOES_t)ptr);
+    ptr = dlsym(gles_android,"glClipPlanefOES"); disp->set_glClipPlanefOES((glClipPlanefOES_t)ptr);
+    ptr = dlsym(gles_android,"glGetClipPlanefOES"); disp->set_glGetClipPlanefOES((glGetClipPlanefOES_t)ptr);
+    ptr = dlsym(gles_android,"glClearDepthfOES"); disp->set_glClearDepthfOES((glClearDepthfOES_t)ptr);
+    ptr = dlsym(gles_android,"glTexGenfOES"); disp->set_glTexGenfOES((glTexGenfOES_t)ptr);
+    ptr = dlsym(gles_android,"glTexGenfvOES"); disp->set_glTexGenfvOES((glTexGenfvOES_t)ptr);
+    ptr = dlsym(gles_android,"glTexGeniOES"); disp->set_glTexGeniOES((glTexGeniOES_t)ptr);
+    ptr = dlsym(gles_android,"glTexGenivOES"); disp->set_glTexGenivOES((glTexGenivOES_t)ptr);
+    ptr = dlsym(gles_android,"glTexGenxOES"); disp->set_glTexGenxOES((glTexGenxOES_t)ptr);
+    ptr = dlsym(gles_android,"glTexGenxvOES"); disp->set_glTexGenxvOES((glTexGenxvOES_t)ptr);
+    ptr = dlsym(gles_android,"glGetTexGenfvOES"); disp->set_glGetTexGenfvOES((glGetTexGenfvOES_t)ptr);
+    ptr = dlsym(gles_android,"glGetTexGenivOES"); disp->set_glGetTexGenivOES((glGetTexGenivOES_t)ptr);
+    ptr = dlsym(gles_android,"glGetTexGenxvOES"); disp->set_glGetTexGenxvOES((glGetTexGenxvOES_t)ptr);
+    ptr = dlsym(gles_android,"glBindVertexArrayOES"); disp->set_glBindVertexArrayOES((glBindVertexArrayOES_t)ptr);
+    ptr = dlsym(gles_android,"glDeleteVertexArraysOES"); disp->set_glDeleteVertexArraysOES((glDeleteVertexArraysOES_t)ptr);
+    ptr = dlsym(gles_android,"glGenVertexArraysOES"); disp->set_glGenVertexArraysOES((glGenVertexArraysOES_t)ptr);
+    ptr = dlsym(gles_android,"glIsVertexArrayOES"); disp->set_glIsVertexArrayOES((glIsVertexArrayOES_t)ptr);
+    ptr = dlsym(gles_android,"glDiscardFramebufferEXT"); disp->set_glDiscardFramebufferEXT((glDiscardFramebufferEXT_t)ptr);
+    ptr = dlsym(gles_android,"glMultiDrawArraysEXT"); disp->set_glMultiDrawArraysEXT((glMultiDrawArraysEXT_t)ptr);
+    ptr = dlsym(gles_android,"glMultiDrawElementsEXT"); disp->set_glMultiDrawElementsEXT((glMultiDrawElementsEXT_t)ptr);
+    ptr = dlsym(gles_android,"glClipPlanefIMG"); disp->set_glClipPlanefIMG((glClipPlanefIMG_t)ptr);
+    ptr = dlsym(gles_android,"glClipPlanexIMG"); disp->set_glClipPlanexIMG((glClipPlanexIMG_t)ptr);
+    ptr = dlsym(gles_android,"glRenderbufferStorageMultisampleIMG"); disp->set_glRenderbufferStorageMultisampleIMG((glRenderbufferStorageMultisampleIMG_t)ptr);
+    ptr = dlsym(gles_android,"glFramebufferTexture2DMultisampleIMG"); disp->set_glFramebufferTexture2DMultisampleIMG((glFramebufferTexture2DMultisampleIMG_t)ptr);
+    ptr = dlsym(gles_android,"glDeleteFencesNV"); disp->set_glDeleteFencesNV((glDeleteFencesNV_t)ptr);
+    ptr = dlsym(gles_android,"glGenFencesNV"); disp->set_glGenFencesNV((glGenFencesNV_t)ptr);
+    ptr = dlsym(gles_android,"glIsFenceNV"); disp->set_glIsFenceNV((glIsFenceNV_t)ptr);
+    ptr = dlsym(gles_android,"glTestFenceNV"); disp->set_glTestFenceNV((glTestFenceNV_t)ptr);
+    ptr = dlsym(gles_android,"glGetFenceivNV"); disp->set_glGetFenceivNV((glGetFenceivNV_t)ptr);
+    ptr = dlsym(gles_android,"glFinishFenceNV"); disp->set_glFinishFenceNV((glFinishFenceNV_t)ptr);
+    ptr = dlsym(gles_android,"glSetFenceNV"); disp->set_glSetFenceNV((glSetFenceNV_t)ptr);
+    ptr = dlsym(gles_android,"glGetDriverControlsQCOM"); disp->set_glGetDriverControlsQCOM((glGetDriverControlsQCOM_t)ptr);
+    ptr = dlsym(gles_android,"glGetDriverControlStringQCOM"); disp->set_glGetDriverControlStringQCOM((glGetDriverControlStringQCOM_t)ptr);
+    ptr = dlsym(gles_android,"glEnableDriverControlQCOM"); disp->set_glEnableDriverControlQCOM((glEnableDriverControlQCOM_t)ptr);
+    ptr = dlsym(gles_android,"glDisableDriverControlQCOM"); disp->set_glDisableDriverControlQCOM((glDisableDriverControlQCOM_t)ptr);
+    ptr = dlsym(gles_android,"glExtGetTexturesQCOM"); disp->set_glExtGetTexturesQCOM((glExtGetTexturesQCOM_t)ptr);
+    ptr = dlsym(gles_android,"glExtGetBuffersQCOM"); disp->set_glExtGetBuffersQCOM((glExtGetBuffersQCOM_t)ptr);
+    ptr = dlsym(gles_android,"glExtGetRenderbuffersQCOM"); disp->set_glExtGetRenderbuffersQCOM((glExtGetRenderbuffersQCOM_t)ptr);
+    ptr = dlsym(gles_android,"glExtGetFramebuffersQCOM"); disp->set_glExtGetFramebuffersQCOM((glExtGetFramebuffersQCOM_t)ptr);
+    ptr = dlsym(gles_android,"glExtGetTexLevelParameterivQCOM"); disp->set_glExtGetTexLevelParameterivQCOM((glExtGetTexLevelParameterivQCOM_t)ptr);
+    ptr = dlsym(gles_android,"glExtTexObjectStateOverrideiQCOM"); disp->set_glExtTexObjectStateOverrideiQCOM((glExtTexObjectStateOverrideiQCOM_t)ptr);
+    ptr = dlsym(gles_android,"glExtGetTexSubImageQCOM"); disp->set_glExtGetTexSubImageQCOM((glExtGetTexSubImageQCOM_t)ptr);
+    ptr = dlsym(gles_android,"glExtGetBufferPointervQCOM"); disp->set_glExtGetBufferPointervQCOM((glExtGetBufferPointervQCOM_t)ptr);
+    ptr = dlsym(gles_android,"glExtGetShadersQCOM"); disp->set_glExtGetShadersQCOM((glExtGetShadersQCOM_t)ptr);
+    ptr = dlsym(gles_android,"glExtGetProgramsQCOM"); disp->set_glExtGetProgramsQCOM((glExtGetProgramsQCOM_t)ptr);
+    ptr = dlsym(gles_android,"glExtIsProgramBinaryQCOM"); disp->set_glExtIsProgramBinaryQCOM((glExtIsProgramBinaryQCOM_t)ptr);
+    ptr = dlsym(gles_android,"glExtGetProgramBinarySourceQCOM"); disp->set_glExtGetProgramBinarySourceQCOM((glExtGetProgramBinarySourceQCOM_t)ptr);
+    ptr = dlsym(gles_android,"glStartTilingQCOM"); disp->set_glStartTilingQCOM((glStartTilingQCOM_t)ptr);
+    ptr = dlsym(gles_android,"glEndTilingQCOM"); disp->set_glEndTilingQCOM((glEndTilingQCOM_t)ptr);
+
+        return disp;
+}
diff --git a/opengl/tests/gles_android_wrapper/gles_dispatch.h b/opengl/tests/gles_android_wrapper/gles_dispatch.h
new file mode 100644
index 0000000..98a4fca
--- /dev/null
+++ b/opengl/tests/gles_android_wrapper/gles_dispatch.h
@@ -0,0 +1,570 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#ifndef _GLES_DISPATCH_H
+#define _GLES_DISPATCH_H
+
+#include "gles_proc.h"
+
+
+struct gles_dispatch {
+    glAlphaFunc_t glAlphaFunc;
+    glClearColor_t glClearColor;
+    glClearDepthf_t glClearDepthf;
+    glClipPlanef_t glClipPlanef;
+    glColor4f_t glColor4f;
+    glDepthRangef_t glDepthRangef;
+    glFogf_t glFogf;
+    glFogfv_t glFogfv;
+    glFrustumf_t glFrustumf;
+    glGetClipPlanef_t glGetClipPlanef;
+    glGetFloatv_t glGetFloatv;
+    glGetLightfv_t glGetLightfv;
+    glGetMaterialfv_t glGetMaterialfv;
+    glGetTexEnvfv_t glGetTexEnvfv;
+    glGetTexParameterfv_t glGetTexParameterfv;
+    glLightModelf_t glLightModelf;
+    glLightModelfv_t glLightModelfv;
+    glLightf_t glLightf;
+    glLightfv_t glLightfv;
+    glLineWidth_t glLineWidth;
+    glLoadMatrixf_t glLoadMatrixf;
+    glMaterialf_t glMaterialf;
+    glMaterialfv_t glMaterialfv;
+    glMultMatrixf_t glMultMatrixf;
+    glMultiTexCoord4f_t glMultiTexCoord4f;
+    glNormal3f_t glNormal3f;
+    glOrthof_t glOrthof;
+    glPointParameterf_t glPointParameterf;
+    glPointParameterfv_t glPointParameterfv;
+    glPointSize_t glPointSize;
+    glPolygonOffset_t glPolygonOffset;
+    glRotatef_t glRotatef;
+    glScalef_t glScalef;
+    glTexEnvf_t glTexEnvf;
+    glTexEnvfv_t glTexEnvfv;
+    glTexParameterf_t glTexParameterf;
+    glTexParameterfv_t glTexParameterfv;
+    glTranslatef_t glTranslatef;
+    glActiveTexture_t glActiveTexture;
+    glAlphaFuncx_t glAlphaFuncx;
+    glBindBuffer_t glBindBuffer;
+    glBindTexture_t glBindTexture;
+    glBlendFunc_t glBlendFunc;
+    glBufferData_t glBufferData;
+    glBufferSubData_t glBufferSubData;
+    glClear_t glClear;
+    glClearColorx_t glClearColorx;
+    glClearDepthx_t glClearDepthx;
+    glClearStencil_t glClearStencil;
+    glClientActiveTexture_t glClientActiveTexture;
+    glClipPlanex_t glClipPlanex;
+    glColor4ub_t glColor4ub;
+    glColor4x_t glColor4x;
+    glColorMask_t glColorMask;
+    glColorPointer_t glColorPointer;
+    glCompressedTexImage2D_t glCompressedTexImage2D;
+    glCompressedTexSubImage2D_t glCompressedTexSubImage2D;
+    glCopyTexImage2D_t glCopyTexImage2D;
+    glCopyTexSubImage2D_t glCopyTexSubImage2D;
+    glCullFace_t glCullFace;
+    glDeleteBuffers_t glDeleteBuffers;
+    glDeleteTextures_t glDeleteTextures;
+    glDepthFunc_t glDepthFunc;
+    glDepthMask_t glDepthMask;
+    glDepthRangex_t glDepthRangex;
+    glDisable_t glDisable;
+    glDisableClientState_t glDisableClientState;
+    glDrawArrays_t glDrawArrays;
+    glDrawElements_t glDrawElements;
+    glEnable_t glEnable;
+    glEnableClientState_t glEnableClientState;
+    glFinish_t glFinish;
+    glFlush_t glFlush;
+    glFogx_t glFogx;
+    glFogxv_t glFogxv;
+    glFrontFace_t glFrontFace;
+    glFrustumx_t glFrustumx;
+    glGetBooleanv_t glGetBooleanv;
+    glGetBufferParameteriv_t glGetBufferParameteriv;
+    glGetClipPlanex_t glGetClipPlanex;
+    glGenBuffers_t glGenBuffers;
+    glGenTextures_t glGenTextures;
+    glGetError_t glGetError;
+    glGetFixedv_t glGetFixedv;
+    glGetIntegerv_t glGetIntegerv;
+    glGetLightxv_t glGetLightxv;
+    glGetMaterialxv_t glGetMaterialxv;
+    glGetPointerv_t glGetPointerv;
+    glGetString_t glGetString;
+    glGetTexEnviv_t glGetTexEnviv;
+    glGetTexEnvxv_t glGetTexEnvxv;
+    glGetTexParameteriv_t glGetTexParameteriv;
+    glGetTexParameterxv_t glGetTexParameterxv;
+    glHint_t glHint;
+    glIsBuffer_t glIsBuffer;
+    glIsEnabled_t glIsEnabled;
+    glIsTexture_t glIsTexture;
+    glLightModelx_t glLightModelx;
+    glLightModelxv_t glLightModelxv;
+    glLightx_t glLightx;
+    glLightxv_t glLightxv;
+    glLineWidthx_t glLineWidthx;
+    glLoadIdentity_t glLoadIdentity;
+    glLoadMatrixx_t glLoadMatrixx;
+    glLogicOp_t glLogicOp;
+    glMaterialx_t glMaterialx;
+    glMaterialxv_t glMaterialxv;
+    glMatrixMode_t glMatrixMode;
+    glMultMatrixx_t glMultMatrixx;
+    glMultiTexCoord4x_t glMultiTexCoord4x;
+    glNormal3x_t glNormal3x;
+    glNormalPointer_t glNormalPointer;
+    glOrthox_t glOrthox;
+    glPixelStorei_t glPixelStorei;
+    glPointParameterx_t glPointParameterx;
+    glPointParameterxv_t glPointParameterxv;
+    glPointSizex_t glPointSizex;
+    glPolygonOffsetx_t glPolygonOffsetx;
+    glPopMatrix_t glPopMatrix;
+    glPushMatrix_t glPushMatrix;
+    glReadPixels_t glReadPixels;
+    glRotatex_t glRotatex;
+    glSampleCoverage_t glSampleCoverage;
+    glSampleCoveragex_t glSampleCoveragex;
+    glScalex_t glScalex;
+    glScissor_t glScissor;
+    glShadeModel_t glShadeModel;
+    glStencilFunc_t glStencilFunc;
+    glStencilMask_t glStencilMask;
+    glStencilOp_t glStencilOp;
+    glTexCoordPointer_t glTexCoordPointer;
+    glTexEnvi_t glTexEnvi;
+    glTexEnvx_t glTexEnvx;
+    glTexEnviv_t glTexEnviv;
+    glTexEnvxv_t glTexEnvxv;
+    glTexImage2D_t glTexImage2D;
+    glTexParameteri_t glTexParameteri;
+    glTexParameterx_t glTexParameterx;
+    glTexParameteriv_t glTexParameteriv;
+    glTexParameterxv_t glTexParameterxv;
+    glTexSubImage2D_t glTexSubImage2D;
+    glTranslatex_t glTranslatex;
+    glVertexPointer_t glVertexPointer;
+    glViewport_t glViewport;
+    glPointSizePointerOES_t glPointSizePointerOES;
+    glBlendEquationSeparateOES_t glBlendEquationSeparateOES;
+    glBlendFuncSeparateOES_t glBlendFuncSeparateOES;
+    glBlendEquationOES_t glBlendEquationOES;
+    glDrawTexsOES_t glDrawTexsOES;
+    glDrawTexiOES_t glDrawTexiOES;
+    glDrawTexxOES_t glDrawTexxOES;
+    glDrawTexsvOES_t glDrawTexsvOES;
+    glDrawTexivOES_t glDrawTexivOES;
+    glDrawTexxvOES_t glDrawTexxvOES;
+    glDrawTexfOES_t glDrawTexfOES;
+    glDrawTexfvOES_t glDrawTexfvOES;
+    glEGLImageTargetTexture2DOES_t glEGLImageTargetTexture2DOES;
+    glEGLImageTargetRenderbufferStorageOES_t glEGLImageTargetRenderbufferStorageOES;
+    glAlphaFuncxOES_t glAlphaFuncxOES;
+    glClearColorxOES_t glClearColorxOES;
+    glClearDepthxOES_t glClearDepthxOES;
+    glClipPlanexOES_t glClipPlanexOES;
+    glColor4xOES_t glColor4xOES;
+    glDepthRangexOES_t glDepthRangexOES;
+    glFogxOES_t glFogxOES;
+    glFogxvOES_t glFogxvOES;
+    glFrustumxOES_t glFrustumxOES;
+    glGetClipPlanexOES_t glGetClipPlanexOES;
+    glGetFixedvOES_t glGetFixedvOES;
+    glGetLightxvOES_t glGetLightxvOES;
+    glGetMaterialxvOES_t glGetMaterialxvOES;
+    glGetTexEnvxvOES_t glGetTexEnvxvOES;
+    glGetTexParameterxvOES_t glGetTexParameterxvOES;
+    glLightModelxOES_t glLightModelxOES;
+    glLightModelxvOES_t glLightModelxvOES;
+    glLightxOES_t glLightxOES;
+    glLightxvOES_t glLightxvOES;
+    glLineWidthxOES_t glLineWidthxOES;
+    glLoadMatrixxOES_t glLoadMatrixxOES;
+    glMaterialxOES_t glMaterialxOES;
+    glMaterialxvOES_t glMaterialxvOES;
+    glMultMatrixxOES_t glMultMatrixxOES;
+    glMultiTexCoord4xOES_t glMultiTexCoord4xOES;
+    glNormal3xOES_t glNormal3xOES;
+    glOrthoxOES_t glOrthoxOES;
+    glPointParameterxOES_t glPointParameterxOES;
+    glPointParameterxvOES_t glPointParameterxvOES;
+    glPointSizexOES_t glPointSizexOES;
+    glPolygonOffsetxOES_t glPolygonOffsetxOES;
+    glRotatexOES_t glRotatexOES;
+    glSampleCoveragexOES_t glSampleCoveragexOES;
+    glScalexOES_t glScalexOES;
+    glTexEnvxOES_t glTexEnvxOES;
+    glTexEnvxvOES_t glTexEnvxvOES;
+    glTexParameterxOES_t glTexParameterxOES;
+    glTexParameterxvOES_t glTexParameterxvOES;
+    glTranslatexOES_t glTranslatexOES;
+    glIsRenderbufferOES_t glIsRenderbufferOES;
+    glBindRenderbufferOES_t glBindRenderbufferOES;
+    glDeleteRenderbuffersOES_t glDeleteRenderbuffersOES;
+    glGenRenderbuffersOES_t glGenRenderbuffersOES;
+    glRenderbufferStorageOES_t glRenderbufferStorageOES;
+    glGetRenderbufferParameterivOES_t glGetRenderbufferParameterivOES;
+    glIsFramebufferOES_t glIsFramebufferOES;
+    glBindFramebufferOES_t glBindFramebufferOES;
+    glDeleteFramebuffersOES_t glDeleteFramebuffersOES;
+    glGenFramebuffersOES_t glGenFramebuffersOES;
+    glCheckFramebufferStatusOES_t glCheckFramebufferStatusOES;
+    glFramebufferRenderbufferOES_t glFramebufferRenderbufferOES;
+    glFramebufferTexture2DOES_t glFramebufferTexture2DOES;
+    glGetFramebufferAttachmentParameterivOES_t glGetFramebufferAttachmentParameterivOES;
+    glGenerateMipmapOES_t glGenerateMipmapOES;
+    glMapBufferOES_t glMapBufferOES;
+    glUnmapBufferOES_t glUnmapBufferOES;
+    glGetBufferPointervOES_t glGetBufferPointervOES;
+    glCurrentPaletteMatrixOES_t glCurrentPaletteMatrixOES;
+    glLoadPaletteFromModelViewMatrixOES_t glLoadPaletteFromModelViewMatrixOES;
+    glMatrixIndexPointerOES_t glMatrixIndexPointerOES;
+    glWeightPointerOES_t glWeightPointerOES;
+    glQueryMatrixxOES_t glQueryMatrixxOES;
+    glDepthRangefOES_t glDepthRangefOES;
+    glFrustumfOES_t glFrustumfOES;
+    glOrthofOES_t glOrthofOES;
+    glClipPlanefOES_t glClipPlanefOES;
+    glGetClipPlanefOES_t glGetClipPlanefOES;
+    glClearDepthfOES_t glClearDepthfOES;
+    glTexGenfOES_t glTexGenfOES;
+    glTexGenfvOES_t glTexGenfvOES;
+    glTexGeniOES_t glTexGeniOES;
+    glTexGenivOES_t glTexGenivOES;
+    glTexGenxOES_t glTexGenxOES;
+    glTexGenxvOES_t glTexGenxvOES;
+    glGetTexGenfvOES_t glGetTexGenfvOES;
+    glGetTexGenivOES_t glGetTexGenivOES;
+    glGetTexGenxvOES_t glGetTexGenxvOES;
+    glBindVertexArrayOES_t glBindVertexArrayOES;
+    glDeleteVertexArraysOES_t glDeleteVertexArraysOES;
+    glGenVertexArraysOES_t glGenVertexArraysOES;
+    glIsVertexArrayOES_t glIsVertexArrayOES;
+    glDiscardFramebufferEXT_t glDiscardFramebufferEXT;
+    glMultiDrawArraysEXT_t glMultiDrawArraysEXT;
+    glMultiDrawElementsEXT_t glMultiDrawElementsEXT;
+    glClipPlanefIMG_t glClipPlanefIMG;
+    glClipPlanexIMG_t glClipPlanexIMG;
+    glRenderbufferStorageMultisampleIMG_t glRenderbufferStorageMultisampleIMG;
+    glFramebufferTexture2DMultisampleIMG_t glFramebufferTexture2DMultisampleIMG;
+    glDeleteFencesNV_t glDeleteFencesNV;
+    glGenFencesNV_t glGenFencesNV;
+    glIsFenceNV_t glIsFenceNV;
+    glTestFenceNV_t glTestFenceNV;
+    glGetFenceivNV_t glGetFenceivNV;
+    glFinishFenceNV_t glFinishFenceNV;
+    glSetFenceNV_t glSetFenceNV;
+    glGetDriverControlsQCOM_t glGetDriverControlsQCOM;
+    glGetDriverControlStringQCOM_t glGetDriverControlStringQCOM;
+    glEnableDriverControlQCOM_t glEnableDriverControlQCOM;
+    glDisableDriverControlQCOM_t glDisableDriverControlQCOM;
+    glExtGetTexturesQCOM_t glExtGetTexturesQCOM;
+    glExtGetBuffersQCOM_t glExtGetBuffersQCOM;
+    glExtGetRenderbuffersQCOM_t glExtGetRenderbuffersQCOM;
+    glExtGetFramebuffersQCOM_t glExtGetFramebuffersQCOM;
+    glExtGetTexLevelParameterivQCOM_t glExtGetTexLevelParameterivQCOM;
+    glExtTexObjectStateOverrideiQCOM_t glExtTexObjectStateOverrideiQCOM;
+    glExtGetTexSubImageQCOM_t glExtGetTexSubImageQCOM;
+    glExtGetBufferPointervQCOM_t glExtGetBufferPointervQCOM;
+    glExtGetShadersQCOM_t glExtGetShadersQCOM;
+    glExtGetProgramsQCOM_t glExtGetProgramsQCOM;
+    glExtIsProgramBinaryQCOM_t glExtIsProgramBinaryQCOM;
+    glExtGetProgramBinarySourceQCOM_t glExtGetProgramBinarySourceQCOM;
+    glStartTilingQCOM_t glStartTilingQCOM;
+    glEndTilingQCOM_t glEndTilingQCOM;
+    //Accessors
+    glAlphaFunc_t set_glAlphaFunc(glAlphaFunc_t f) { glAlphaFunc_t retval = glAlphaFunc; glAlphaFunc = f; return retval;}
+    glClearColor_t set_glClearColor(glClearColor_t f) { glClearColor_t retval = glClearColor; glClearColor = f; return retval;}
+    glClearDepthf_t set_glClearDepthf(glClearDepthf_t f) { glClearDepthf_t retval = glClearDepthf; glClearDepthf = f; return retval;}
+    glClipPlanef_t set_glClipPlanef(glClipPlanef_t f) { glClipPlanef_t retval = glClipPlanef; glClipPlanef = f; return retval;}
+    glColor4f_t set_glColor4f(glColor4f_t f) { glColor4f_t retval = glColor4f; glColor4f = f; return retval;}
+    glDepthRangef_t set_glDepthRangef(glDepthRangef_t f) { glDepthRangef_t retval = glDepthRangef; glDepthRangef = f; return retval;}
+    glFogf_t set_glFogf(glFogf_t f) { glFogf_t retval = glFogf; glFogf = f; return retval;}
+    glFogfv_t set_glFogfv(glFogfv_t f) { glFogfv_t retval = glFogfv; glFogfv = f; return retval;}
+    glFrustumf_t set_glFrustumf(glFrustumf_t f) { glFrustumf_t retval = glFrustumf; glFrustumf = f; return retval;}
+    glGetClipPlanef_t set_glGetClipPlanef(glGetClipPlanef_t f) { glGetClipPlanef_t retval = glGetClipPlanef; glGetClipPlanef = f; return retval;}
+    glGetFloatv_t set_glGetFloatv(glGetFloatv_t f) { glGetFloatv_t retval = glGetFloatv; glGetFloatv = f; return retval;}
+    glGetLightfv_t set_glGetLightfv(glGetLightfv_t f) { glGetLightfv_t retval = glGetLightfv; glGetLightfv = f; return retval;}
+    glGetMaterialfv_t set_glGetMaterialfv(glGetMaterialfv_t f) { glGetMaterialfv_t retval = glGetMaterialfv; glGetMaterialfv = f; return retval;}
+    glGetTexEnvfv_t set_glGetTexEnvfv(glGetTexEnvfv_t f) { glGetTexEnvfv_t retval = glGetTexEnvfv; glGetTexEnvfv = f; return retval;}
+    glGetTexParameterfv_t set_glGetTexParameterfv(glGetTexParameterfv_t f) { glGetTexParameterfv_t retval = glGetTexParameterfv; glGetTexParameterfv = f; return retval;}
+    glLightModelf_t set_glLightModelf(glLightModelf_t f) { glLightModelf_t retval = glLightModelf; glLightModelf = f; return retval;}
+    glLightModelfv_t set_glLightModelfv(glLightModelfv_t f) { glLightModelfv_t retval = glLightModelfv; glLightModelfv = f; return retval;}
+    glLightf_t set_glLightf(glLightf_t f) { glLightf_t retval = glLightf; glLightf = f; return retval;}
+    glLightfv_t set_glLightfv(glLightfv_t f) { glLightfv_t retval = glLightfv; glLightfv = f; return retval;}
+    glLineWidth_t set_glLineWidth(glLineWidth_t f) { glLineWidth_t retval = glLineWidth; glLineWidth = f; return retval;}
+    glLoadMatrixf_t set_glLoadMatrixf(glLoadMatrixf_t f) { glLoadMatrixf_t retval = glLoadMatrixf; glLoadMatrixf = f; return retval;}
+    glMaterialf_t set_glMaterialf(glMaterialf_t f) { glMaterialf_t retval = glMaterialf; glMaterialf = f; return retval;}
+    glMaterialfv_t set_glMaterialfv(glMaterialfv_t f) { glMaterialfv_t retval = glMaterialfv; glMaterialfv = f; return retval;}
+    glMultMatrixf_t set_glMultMatrixf(glMultMatrixf_t f) { glMultMatrixf_t retval = glMultMatrixf; glMultMatrixf = f; return retval;}
+    glMultiTexCoord4f_t set_glMultiTexCoord4f(glMultiTexCoord4f_t f) { glMultiTexCoord4f_t retval = glMultiTexCoord4f; glMultiTexCoord4f = f; return retval;}
+    glNormal3f_t set_glNormal3f(glNormal3f_t f) { glNormal3f_t retval = glNormal3f; glNormal3f = f; return retval;}
+    glOrthof_t set_glOrthof(glOrthof_t f) { glOrthof_t retval = glOrthof; glOrthof = f; return retval;}
+    glPointParameterf_t set_glPointParameterf(glPointParameterf_t f) { glPointParameterf_t retval = glPointParameterf; glPointParameterf = f; return retval;}
+    glPointParameterfv_t set_glPointParameterfv(glPointParameterfv_t f) { glPointParameterfv_t retval = glPointParameterfv; glPointParameterfv = f; return retval;}
+    glPointSize_t set_glPointSize(glPointSize_t f) { glPointSize_t retval = glPointSize; glPointSize = f; return retval;}
+    glPolygonOffset_t set_glPolygonOffset(glPolygonOffset_t f) { glPolygonOffset_t retval = glPolygonOffset; glPolygonOffset = f; return retval;}
+    glRotatef_t set_glRotatef(glRotatef_t f) { glRotatef_t retval = glRotatef; glRotatef = f; return retval;}
+    glScalef_t set_glScalef(glScalef_t f) { glScalef_t retval = glScalef; glScalef = f; return retval;}
+    glTexEnvf_t set_glTexEnvf(glTexEnvf_t f) { glTexEnvf_t retval = glTexEnvf; glTexEnvf = f; return retval;}
+    glTexEnvfv_t set_glTexEnvfv(glTexEnvfv_t f) { glTexEnvfv_t retval = glTexEnvfv; glTexEnvfv = f; return retval;}
+    glTexParameterf_t set_glTexParameterf(glTexParameterf_t f) { glTexParameterf_t retval = glTexParameterf; glTexParameterf = f; return retval;}
+    glTexParameterfv_t set_glTexParameterfv(glTexParameterfv_t f) { glTexParameterfv_t retval = glTexParameterfv; glTexParameterfv = f; return retval;}
+    glTranslatef_t set_glTranslatef(glTranslatef_t f) { glTranslatef_t retval = glTranslatef; glTranslatef = f; return retval;}
+    glActiveTexture_t set_glActiveTexture(glActiveTexture_t f) { glActiveTexture_t retval = glActiveTexture; glActiveTexture = f; return retval;}
+    glAlphaFuncx_t set_glAlphaFuncx(glAlphaFuncx_t f) { glAlphaFuncx_t retval = glAlphaFuncx; glAlphaFuncx = f; return retval;}
+    glBindBuffer_t set_glBindBuffer(glBindBuffer_t f) { glBindBuffer_t retval = glBindBuffer; glBindBuffer = f; return retval;}
+    glBindTexture_t set_glBindTexture(glBindTexture_t f) { glBindTexture_t retval = glBindTexture; glBindTexture = f; return retval;}
+    glBlendFunc_t set_glBlendFunc(glBlendFunc_t f) { glBlendFunc_t retval = glBlendFunc; glBlendFunc = f; return retval;}
+    glBufferData_t set_glBufferData(glBufferData_t f) { glBufferData_t retval = glBufferData; glBufferData = f; return retval;}
+    glBufferSubData_t set_glBufferSubData(glBufferSubData_t f) { glBufferSubData_t retval = glBufferSubData; glBufferSubData = f; return retval;}
+    glClear_t set_glClear(glClear_t f) { glClear_t retval = glClear; glClear = f; return retval;}
+    glClearColorx_t set_glClearColorx(glClearColorx_t f) { glClearColorx_t retval = glClearColorx; glClearColorx = f; return retval;}
+    glClearDepthx_t set_glClearDepthx(glClearDepthx_t f) { glClearDepthx_t retval = glClearDepthx; glClearDepthx = f; return retval;}
+    glClearStencil_t set_glClearStencil(glClearStencil_t f) { glClearStencil_t retval = glClearStencil; glClearStencil = f; return retval;}
+    glClientActiveTexture_t set_glClientActiveTexture(glClientActiveTexture_t f) { glClientActiveTexture_t retval = glClientActiveTexture; glClientActiveTexture = f; return retval;}
+    glClipPlanex_t set_glClipPlanex(glClipPlanex_t f) { glClipPlanex_t retval = glClipPlanex; glClipPlanex = f; return retval;}
+    glColor4ub_t set_glColor4ub(glColor4ub_t f) { glColor4ub_t retval = glColor4ub; glColor4ub = f; return retval;}
+    glColor4x_t set_glColor4x(glColor4x_t f) { glColor4x_t retval = glColor4x; glColor4x = f; return retval;}
+    glColorMask_t set_glColorMask(glColorMask_t f) { glColorMask_t retval = glColorMask; glColorMask = f; return retval;}
+    glColorPointer_t set_glColorPointer(glColorPointer_t f) { glColorPointer_t retval = glColorPointer; glColorPointer = f; return retval;}
+    glCompressedTexImage2D_t set_glCompressedTexImage2D(glCompressedTexImage2D_t f) { glCompressedTexImage2D_t retval = glCompressedTexImage2D; glCompressedTexImage2D = f; return retval;}
+    glCompressedTexSubImage2D_t set_glCompressedTexSubImage2D(glCompressedTexSubImage2D_t f) { glCompressedTexSubImage2D_t retval = glCompressedTexSubImage2D; glCompressedTexSubImage2D = f; return retval;}
+    glCopyTexImage2D_t set_glCopyTexImage2D(glCopyTexImage2D_t f) { glCopyTexImage2D_t retval = glCopyTexImage2D; glCopyTexImage2D = f; return retval;}
+    glCopyTexSubImage2D_t set_glCopyTexSubImage2D(glCopyTexSubImage2D_t f) { glCopyTexSubImage2D_t retval = glCopyTexSubImage2D; glCopyTexSubImage2D = f; return retval;}
+    glCullFace_t set_glCullFace(glCullFace_t f) { glCullFace_t retval = glCullFace; glCullFace = f; return retval;}
+    glDeleteBuffers_t set_glDeleteBuffers(glDeleteBuffers_t f) { glDeleteBuffers_t retval = glDeleteBuffers; glDeleteBuffers = f; return retval;}
+    glDeleteTextures_t set_glDeleteTextures(glDeleteTextures_t f) { glDeleteTextures_t retval = glDeleteTextures; glDeleteTextures = f; return retval;}
+    glDepthFunc_t set_glDepthFunc(glDepthFunc_t f) { glDepthFunc_t retval = glDepthFunc; glDepthFunc = f; return retval;}
+    glDepthMask_t set_glDepthMask(glDepthMask_t f) { glDepthMask_t retval = glDepthMask; glDepthMask = f; return retval;}
+    glDepthRangex_t set_glDepthRangex(glDepthRangex_t f) { glDepthRangex_t retval = glDepthRangex; glDepthRangex = f; return retval;}
+    glDisable_t set_glDisable(glDisable_t f) { glDisable_t retval = glDisable; glDisable = f; return retval;}
+    glDisableClientState_t set_glDisableClientState(glDisableClientState_t f) { glDisableClientState_t retval = glDisableClientState; glDisableClientState = f; return retval;}
+    glDrawArrays_t set_glDrawArrays(glDrawArrays_t f) { glDrawArrays_t retval = glDrawArrays; glDrawArrays = f; return retval;}
+    glDrawElements_t set_glDrawElements(glDrawElements_t f) { glDrawElements_t retval = glDrawElements; glDrawElements = f; return retval;}
+    glEnable_t set_glEnable(glEnable_t f) { glEnable_t retval = glEnable; glEnable = f; return retval;}
+    glEnableClientState_t set_glEnableClientState(glEnableClientState_t f) { glEnableClientState_t retval = glEnableClientState; glEnableClientState = f; return retval;}
+    glFinish_t set_glFinish(glFinish_t f) { glFinish_t retval = glFinish; glFinish = f; return retval;}
+    glFlush_t set_glFlush(glFlush_t f) { glFlush_t retval = glFlush; glFlush = f; return retval;}
+    glFogx_t set_glFogx(glFogx_t f) { glFogx_t retval = glFogx; glFogx = f; return retval;}
+    glFogxv_t set_glFogxv(glFogxv_t f) { glFogxv_t retval = glFogxv; glFogxv = f; return retval;}
+    glFrontFace_t set_glFrontFace(glFrontFace_t f) { glFrontFace_t retval = glFrontFace; glFrontFace = f; return retval;}
+    glFrustumx_t set_glFrustumx(glFrustumx_t f) { glFrustumx_t retval = glFrustumx; glFrustumx = f; return retval;}
+    glGetBooleanv_t set_glGetBooleanv(glGetBooleanv_t f) { glGetBooleanv_t retval = glGetBooleanv; glGetBooleanv = f; return retval;}
+    glGetBufferParameteriv_t set_glGetBufferParameteriv(glGetBufferParameteriv_t f) { glGetBufferParameteriv_t retval = glGetBufferParameteriv; glGetBufferParameteriv = f; return retval;}
+    glGetClipPlanex_t set_glGetClipPlanex(glGetClipPlanex_t f) { glGetClipPlanex_t retval = glGetClipPlanex; glGetClipPlanex = f; return retval;}
+    glGenBuffers_t set_glGenBuffers(glGenBuffers_t f) { glGenBuffers_t retval = glGenBuffers; glGenBuffers = f; return retval;}
+    glGenTextures_t set_glGenTextures(glGenTextures_t f) { glGenTextures_t retval = glGenTextures; glGenTextures = f; return retval;}
+    glGetError_t set_glGetError(glGetError_t f) { glGetError_t retval = glGetError; glGetError = f; return retval;}
+    glGetFixedv_t set_glGetFixedv(glGetFixedv_t f) { glGetFixedv_t retval = glGetFixedv; glGetFixedv = f; return retval;}
+    glGetIntegerv_t set_glGetIntegerv(glGetIntegerv_t f) { glGetIntegerv_t retval = glGetIntegerv; glGetIntegerv = f; return retval;}
+    glGetLightxv_t set_glGetLightxv(glGetLightxv_t f) { glGetLightxv_t retval = glGetLightxv; glGetLightxv = f; return retval;}
+    glGetMaterialxv_t set_glGetMaterialxv(glGetMaterialxv_t f) { glGetMaterialxv_t retval = glGetMaterialxv; glGetMaterialxv = f; return retval;}
+    glGetPointerv_t set_glGetPointerv(glGetPointerv_t f) { glGetPointerv_t retval = glGetPointerv; glGetPointerv = f; return retval;}
+    glGetString_t set_glGetString(glGetString_t f) { glGetString_t retval = glGetString; glGetString = f; return retval;}
+    glGetTexEnviv_t set_glGetTexEnviv(glGetTexEnviv_t f) { glGetTexEnviv_t retval = glGetTexEnviv; glGetTexEnviv = f; return retval;}
+    glGetTexEnvxv_t set_glGetTexEnvxv(glGetTexEnvxv_t f) { glGetTexEnvxv_t retval = glGetTexEnvxv; glGetTexEnvxv = f; return retval;}
+    glGetTexParameteriv_t set_glGetTexParameteriv(glGetTexParameteriv_t f) { glGetTexParameteriv_t retval = glGetTexParameteriv; glGetTexParameteriv = f; return retval;}
+    glGetTexParameterxv_t set_glGetTexParameterxv(glGetTexParameterxv_t f) { glGetTexParameterxv_t retval = glGetTexParameterxv; glGetTexParameterxv = f; return retval;}
+    glHint_t set_glHint(glHint_t f) { glHint_t retval = glHint; glHint = f; return retval;}
+    glIsBuffer_t set_glIsBuffer(glIsBuffer_t f) { glIsBuffer_t retval = glIsBuffer; glIsBuffer = f; return retval;}
+    glIsEnabled_t set_glIsEnabled(glIsEnabled_t f) { glIsEnabled_t retval = glIsEnabled; glIsEnabled = f; return retval;}
+    glIsTexture_t set_glIsTexture(glIsTexture_t f) { glIsTexture_t retval = glIsTexture; glIsTexture = f; return retval;}
+    glLightModelx_t set_glLightModelx(glLightModelx_t f) { glLightModelx_t retval = glLightModelx; glLightModelx = f; return retval;}
+    glLightModelxv_t set_glLightModelxv(glLightModelxv_t f) { glLightModelxv_t retval = glLightModelxv; glLightModelxv = f; return retval;}
+    glLightx_t set_glLightx(glLightx_t f) { glLightx_t retval = glLightx; glLightx = f; return retval;}
+    glLightxv_t set_glLightxv(glLightxv_t f) { glLightxv_t retval = glLightxv; glLightxv = f; return retval;}
+    glLineWidthx_t set_glLineWidthx(glLineWidthx_t f) { glLineWidthx_t retval = glLineWidthx; glLineWidthx = f; return retval;}
+    glLoadIdentity_t set_glLoadIdentity(glLoadIdentity_t f) { glLoadIdentity_t retval = glLoadIdentity; glLoadIdentity = f; return retval;}
+    glLoadMatrixx_t set_glLoadMatrixx(glLoadMatrixx_t f) { glLoadMatrixx_t retval = glLoadMatrixx; glLoadMatrixx = f; return retval;}
+    glLogicOp_t set_glLogicOp(glLogicOp_t f) { glLogicOp_t retval = glLogicOp; glLogicOp = f; return retval;}
+    glMaterialx_t set_glMaterialx(glMaterialx_t f) { glMaterialx_t retval = glMaterialx; glMaterialx = f; return retval;}
+    glMaterialxv_t set_glMaterialxv(glMaterialxv_t f) { glMaterialxv_t retval = glMaterialxv; glMaterialxv = f; return retval;}
+    glMatrixMode_t set_glMatrixMode(glMatrixMode_t f) { glMatrixMode_t retval = glMatrixMode; glMatrixMode = f; return retval;}
+    glMultMatrixx_t set_glMultMatrixx(glMultMatrixx_t f) { glMultMatrixx_t retval = glMultMatrixx; glMultMatrixx = f; return retval;}
+    glMultiTexCoord4x_t set_glMultiTexCoord4x(glMultiTexCoord4x_t f) { glMultiTexCoord4x_t retval = glMultiTexCoord4x; glMultiTexCoord4x = f; return retval;}
+    glNormal3x_t set_glNormal3x(glNormal3x_t f) { glNormal3x_t retval = glNormal3x; glNormal3x = f; return retval;}
+    glNormalPointer_t set_glNormalPointer(glNormalPointer_t f) { glNormalPointer_t retval = glNormalPointer; glNormalPointer = f; return retval;}
+    glOrthox_t set_glOrthox(glOrthox_t f) { glOrthox_t retval = glOrthox; glOrthox = f; return retval;}
+    glPixelStorei_t set_glPixelStorei(glPixelStorei_t f) { glPixelStorei_t retval = glPixelStorei; glPixelStorei = f; return retval;}
+    glPointParameterx_t set_glPointParameterx(glPointParameterx_t f) { glPointParameterx_t retval = glPointParameterx; glPointParameterx = f; return retval;}
+    glPointParameterxv_t set_glPointParameterxv(glPointParameterxv_t f) { glPointParameterxv_t retval = glPointParameterxv; glPointParameterxv = f; return retval;}
+    glPointSizex_t set_glPointSizex(glPointSizex_t f) { glPointSizex_t retval = glPointSizex; glPointSizex = f; return retval;}
+    glPolygonOffsetx_t set_glPolygonOffsetx(glPolygonOffsetx_t f) { glPolygonOffsetx_t retval = glPolygonOffsetx; glPolygonOffsetx = f; return retval;}
+    glPopMatrix_t set_glPopMatrix(glPopMatrix_t f) { glPopMatrix_t retval = glPopMatrix; glPopMatrix = f; return retval;}
+    glPushMatrix_t set_glPushMatrix(glPushMatrix_t f) { glPushMatrix_t retval = glPushMatrix; glPushMatrix = f; return retval;}
+    glReadPixels_t set_glReadPixels(glReadPixels_t f) { glReadPixels_t retval = glReadPixels; glReadPixels = f; return retval;}
+    glRotatex_t set_glRotatex(glRotatex_t f) { glRotatex_t retval = glRotatex; glRotatex = f; return retval;}
+    glSampleCoverage_t set_glSampleCoverage(glSampleCoverage_t f) { glSampleCoverage_t retval = glSampleCoverage; glSampleCoverage = f; return retval;}
+    glSampleCoveragex_t set_glSampleCoveragex(glSampleCoveragex_t f) { glSampleCoveragex_t retval = glSampleCoveragex; glSampleCoveragex = f; return retval;}
+    glScalex_t set_glScalex(glScalex_t f) { glScalex_t retval = glScalex; glScalex = f; return retval;}
+    glScissor_t set_glScissor(glScissor_t f) { glScissor_t retval = glScissor; glScissor = f; return retval;}
+    glShadeModel_t set_glShadeModel(glShadeModel_t f) { glShadeModel_t retval = glShadeModel; glShadeModel = f; return retval;}
+    glStencilFunc_t set_glStencilFunc(glStencilFunc_t f) { glStencilFunc_t retval = glStencilFunc; glStencilFunc = f; return retval;}
+    glStencilMask_t set_glStencilMask(glStencilMask_t f) { glStencilMask_t retval = glStencilMask; glStencilMask = f; return retval;}
+    glStencilOp_t set_glStencilOp(glStencilOp_t f) { glStencilOp_t retval = glStencilOp; glStencilOp = f; return retval;}
+    glTexCoordPointer_t set_glTexCoordPointer(glTexCoordPointer_t f) { glTexCoordPointer_t retval = glTexCoordPointer; glTexCoordPointer = f; return retval;}
+    glTexEnvi_t set_glTexEnvi(glTexEnvi_t f) { glTexEnvi_t retval = glTexEnvi; glTexEnvi = f; return retval;}
+    glTexEnvx_t set_glTexEnvx(glTexEnvx_t f) { glTexEnvx_t retval = glTexEnvx; glTexEnvx = f; return retval;}
+    glTexEnviv_t set_glTexEnviv(glTexEnviv_t f) { glTexEnviv_t retval = glTexEnviv; glTexEnviv = f; return retval;}
+    glTexEnvxv_t set_glTexEnvxv(glTexEnvxv_t f) { glTexEnvxv_t retval = glTexEnvxv; glTexEnvxv = f; return retval;}
+    glTexImage2D_t set_glTexImage2D(glTexImage2D_t f) { glTexImage2D_t retval = glTexImage2D; glTexImage2D = f; return retval;}
+    glTexParameteri_t set_glTexParameteri(glTexParameteri_t f) { glTexParameteri_t retval = glTexParameteri; glTexParameteri = f; return retval;}
+    glTexParameterx_t set_glTexParameterx(glTexParameterx_t f) { glTexParameterx_t retval = glTexParameterx; glTexParameterx = f; return retval;}
+    glTexParameteriv_t set_glTexParameteriv(glTexParameteriv_t f) { glTexParameteriv_t retval = glTexParameteriv; glTexParameteriv = f; return retval;}
+    glTexParameterxv_t set_glTexParameterxv(glTexParameterxv_t f) { glTexParameterxv_t retval = glTexParameterxv; glTexParameterxv = f; return retval;}
+    glTexSubImage2D_t set_glTexSubImage2D(glTexSubImage2D_t f) { glTexSubImage2D_t retval = glTexSubImage2D; glTexSubImage2D = f; return retval;}
+    glTranslatex_t set_glTranslatex(glTranslatex_t f) { glTranslatex_t retval = glTranslatex; glTranslatex = f; return retval;}
+    glVertexPointer_t set_glVertexPointer(glVertexPointer_t f) { glVertexPointer_t retval = glVertexPointer; glVertexPointer = f; return retval;}
+    glViewport_t set_glViewport(glViewport_t f) { glViewport_t retval = glViewport; glViewport = f; return retval;}
+    glPointSizePointerOES_t set_glPointSizePointerOES(glPointSizePointerOES_t f) { glPointSizePointerOES_t retval = glPointSizePointerOES; glPointSizePointerOES = f; return retval;}
+    glBlendEquationSeparateOES_t set_glBlendEquationSeparateOES(glBlendEquationSeparateOES_t f) { glBlendEquationSeparateOES_t retval = glBlendEquationSeparateOES; glBlendEquationSeparateOES = f; return retval;}
+    glBlendFuncSeparateOES_t set_glBlendFuncSeparateOES(glBlendFuncSeparateOES_t f) { glBlendFuncSeparateOES_t retval = glBlendFuncSeparateOES; glBlendFuncSeparateOES = f; return retval;}
+    glBlendEquationOES_t set_glBlendEquationOES(glBlendEquationOES_t f) { glBlendEquationOES_t retval = glBlendEquationOES; glBlendEquationOES = f; return retval;}
+    glDrawTexsOES_t set_glDrawTexsOES(glDrawTexsOES_t f) { glDrawTexsOES_t retval = glDrawTexsOES; glDrawTexsOES = f; return retval;}
+    glDrawTexiOES_t set_glDrawTexiOES(glDrawTexiOES_t f) { glDrawTexiOES_t retval = glDrawTexiOES; glDrawTexiOES = f; return retval;}
+    glDrawTexxOES_t set_glDrawTexxOES(glDrawTexxOES_t f) { glDrawTexxOES_t retval = glDrawTexxOES; glDrawTexxOES = f; return retval;}
+    glDrawTexsvOES_t set_glDrawTexsvOES(glDrawTexsvOES_t f) { glDrawTexsvOES_t retval = glDrawTexsvOES; glDrawTexsvOES = f; return retval;}
+    glDrawTexivOES_t set_glDrawTexivOES(glDrawTexivOES_t f) { glDrawTexivOES_t retval = glDrawTexivOES; glDrawTexivOES = f; return retval;}
+    glDrawTexxvOES_t set_glDrawTexxvOES(glDrawTexxvOES_t f) { glDrawTexxvOES_t retval = glDrawTexxvOES; glDrawTexxvOES = f; return retval;}
+    glDrawTexfOES_t set_glDrawTexfOES(glDrawTexfOES_t f) { glDrawTexfOES_t retval = glDrawTexfOES; glDrawTexfOES = f; return retval;}
+    glDrawTexfvOES_t set_glDrawTexfvOES(glDrawTexfvOES_t f) { glDrawTexfvOES_t retval = glDrawTexfvOES; glDrawTexfvOES = f; return retval;}
+    glEGLImageTargetTexture2DOES_t set_glEGLImageTargetTexture2DOES(glEGLImageTargetTexture2DOES_t f) { glEGLImageTargetTexture2DOES_t retval = glEGLImageTargetTexture2DOES; glEGLImageTargetTexture2DOES = f; return retval;}
+    glEGLImageTargetRenderbufferStorageOES_t set_glEGLImageTargetRenderbufferStorageOES(glEGLImageTargetRenderbufferStorageOES_t f) { glEGLImageTargetRenderbufferStorageOES_t retval = glEGLImageTargetRenderbufferStorageOES; glEGLImageTargetRenderbufferStorageOES = f; return retval;}
+    glAlphaFuncxOES_t set_glAlphaFuncxOES(glAlphaFuncxOES_t f) { glAlphaFuncxOES_t retval = glAlphaFuncxOES; glAlphaFuncxOES = f; return retval;}
+    glClearColorxOES_t set_glClearColorxOES(glClearColorxOES_t f) { glClearColorxOES_t retval = glClearColorxOES; glClearColorxOES = f; return retval;}
+    glClearDepthxOES_t set_glClearDepthxOES(glClearDepthxOES_t f) { glClearDepthxOES_t retval = glClearDepthxOES; glClearDepthxOES = f; return retval;}
+    glClipPlanexOES_t set_glClipPlanexOES(glClipPlanexOES_t f) { glClipPlanexOES_t retval = glClipPlanexOES; glClipPlanexOES = f; return retval;}
+    glColor4xOES_t set_glColor4xOES(glColor4xOES_t f) { glColor4xOES_t retval = glColor4xOES; glColor4xOES = f; return retval;}
+    glDepthRangexOES_t set_glDepthRangexOES(glDepthRangexOES_t f) { glDepthRangexOES_t retval = glDepthRangexOES; glDepthRangexOES = f; return retval;}
+    glFogxOES_t set_glFogxOES(glFogxOES_t f) { glFogxOES_t retval = glFogxOES; glFogxOES = f; return retval;}
+    glFogxvOES_t set_glFogxvOES(glFogxvOES_t f) { glFogxvOES_t retval = glFogxvOES; glFogxvOES = f; return retval;}
+    glFrustumxOES_t set_glFrustumxOES(glFrustumxOES_t f) { glFrustumxOES_t retval = glFrustumxOES; glFrustumxOES = f; return retval;}
+    glGetClipPlanexOES_t set_glGetClipPlanexOES(glGetClipPlanexOES_t f) { glGetClipPlanexOES_t retval = glGetClipPlanexOES; glGetClipPlanexOES = f; return retval;}
+    glGetFixedvOES_t set_glGetFixedvOES(glGetFixedvOES_t f) { glGetFixedvOES_t retval = glGetFixedvOES; glGetFixedvOES = f; return retval;}
+    glGetLightxvOES_t set_glGetLightxvOES(glGetLightxvOES_t f) { glGetLightxvOES_t retval = glGetLightxvOES; glGetLightxvOES = f; return retval;}
+    glGetMaterialxvOES_t set_glGetMaterialxvOES(glGetMaterialxvOES_t f) { glGetMaterialxvOES_t retval = glGetMaterialxvOES; glGetMaterialxvOES = f; return retval;}
+    glGetTexEnvxvOES_t set_glGetTexEnvxvOES(glGetTexEnvxvOES_t f) { glGetTexEnvxvOES_t retval = glGetTexEnvxvOES; glGetTexEnvxvOES = f; return retval;}
+    glGetTexParameterxvOES_t set_glGetTexParameterxvOES(glGetTexParameterxvOES_t f) { glGetTexParameterxvOES_t retval = glGetTexParameterxvOES; glGetTexParameterxvOES = f; return retval;}
+    glLightModelxOES_t set_glLightModelxOES(glLightModelxOES_t f) { glLightModelxOES_t retval = glLightModelxOES; glLightModelxOES = f; return retval;}
+    glLightModelxvOES_t set_glLightModelxvOES(glLightModelxvOES_t f) { glLightModelxvOES_t retval = glLightModelxvOES; glLightModelxvOES = f; return retval;}
+    glLightxOES_t set_glLightxOES(glLightxOES_t f) { glLightxOES_t retval = glLightxOES; glLightxOES = f; return retval;}
+    glLightxvOES_t set_glLightxvOES(glLightxvOES_t f) { glLightxvOES_t retval = glLightxvOES; glLightxvOES = f; return retval;}
+    glLineWidthxOES_t set_glLineWidthxOES(glLineWidthxOES_t f) { glLineWidthxOES_t retval = glLineWidthxOES; glLineWidthxOES = f; return retval;}
+    glLoadMatrixxOES_t set_glLoadMatrixxOES(glLoadMatrixxOES_t f) { glLoadMatrixxOES_t retval = glLoadMatrixxOES; glLoadMatrixxOES = f; return retval;}
+    glMaterialxOES_t set_glMaterialxOES(glMaterialxOES_t f) { glMaterialxOES_t retval = glMaterialxOES; glMaterialxOES = f; return retval;}
+    glMaterialxvOES_t set_glMaterialxvOES(glMaterialxvOES_t f) { glMaterialxvOES_t retval = glMaterialxvOES; glMaterialxvOES = f; return retval;}
+    glMultMatrixxOES_t set_glMultMatrixxOES(glMultMatrixxOES_t f) { glMultMatrixxOES_t retval = glMultMatrixxOES; glMultMatrixxOES = f; return retval;}
+    glMultiTexCoord4xOES_t set_glMultiTexCoord4xOES(glMultiTexCoord4xOES_t f) { glMultiTexCoord4xOES_t retval = glMultiTexCoord4xOES; glMultiTexCoord4xOES = f; return retval;}
+    glNormal3xOES_t set_glNormal3xOES(glNormal3xOES_t f) { glNormal3xOES_t retval = glNormal3xOES; glNormal3xOES = f; return retval;}
+    glOrthoxOES_t set_glOrthoxOES(glOrthoxOES_t f) { glOrthoxOES_t retval = glOrthoxOES; glOrthoxOES = f; return retval;}
+    glPointParameterxOES_t set_glPointParameterxOES(glPointParameterxOES_t f) { glPointParameterxOES_t retval = glPointParameterxOES; glPointParameterxOES = f; return retval;}
+    glPointParameterxvOES_t set_glPointParameterxvOES(glPointParameterxvOES_t f) { glPointParameterxvOES_t retval = glPointParameterxvOES; glPointParameterxvOES = f; return retval;}
+    glPointSizexOES_t set_glPointSizexOES(glPointSizexOES_t f) { glPointSizexOES_t retval = glPointSizexOES; glPointSizexOES = f; return retval;}
+    glPolygonOffsetxOES_t set_glPolygonOffsetxOES(glPolygonOffsetxOES_t f) { glPolygonOffsetxOES_t retval = glPolygonOffsetxOES; glPolygonOffsetxOES = f; return retval;}
+    glRotatexOES_t set_glRotatexOES(glRotatexOES_t f) { glRotatexOES_t retval = glRotatexOES; glRotatexOES = f; return retval;}
+    glSampleCoveragexOES_t set_glSampleCoveragexOES(glSampleCoveragexOES_t f) { glSampleCoveragexOES_t retval = glSampleCoveragexOES; glSampleCoveragexOES = f; return retval;}
+    glScalexOES_t set_glScalexOES(glScalexOES_t f) { glScalexOES_t retval = glScalexOES; glScalexOES = f; return retval;}
+    glTexEnvxOES_t set_glTexEnvxOES(glTexEnvxOES_t f) { glTexEnvxOES_t retval = glTexEnvxOES; glTexEnvxOES = f; return retval;}
+    glTexEnvxvOES_t set_glTexEnvxvOES(glTexEnvxvOES_t f) { glTexEnvxvOES_t retval = glTexEnvxvOES; glTexEnvxvOES = f; return retval;}
+    glTexParameterxOES_t set_glTexParameterxOES(glTexParameterxOES_t f) { glTexParameterxOES_t retval = glTexParameterxOES; glTexParameterxOES = f; return retval;}
+    glTexParameterxvOES_t set_glTexParameterxvOES(glTexParameterxvOES_t f) { glTexParameterxvOES_t retval = glTexParameterxvOES; glTexParameterxvOES = f; return retval;}
+    glTranslatexOES_t set_glTranslatexOES(glTranslatexOES_t f) { glTranslatexOES_t retval = glTranslatexOES; glTranslatexOES = f; return retval;}
+    glIsRenderbufferOES_t set_glIsRenderbufferOES(glIsRenderbufferOES_t f) { glIsRenderbufferOES_t retval = glIsRenderbufferOES; glIsRenderbufferOES = f; return retval;}
+    glBindRenderbufferOES_t set_glBindRenderbufferOES(glBindRenderbufferOES_t f) { glBindRenderbufferOES_t retval = glBindRenderbufferOES; glBindRenderbufferOES = f; return retval;}
+    glDeleteRenderbuffersOES_t set_glDeleteRenderbuffersOES(glDeleteRenderbuffersOES_t f) { glDeleteRenderbuffersOES_t retval = glDeleteRenderbuffersOES; glDeleteRenderbuffersOES = f; return retval;}
+    glGenRenderbuffersOES_t set_glGenRenderbuffersOES(glGenRenderbuffersOES_t f) { glGenRenderbuffersOES_t retval = glGenRenderbuffersOES; glGenRenderbuffersOES = f; return retval;}
+    glRenderbufferStorageOES_t set_glRenderbufferStorageOES(glRenderbufferStorageOES_t f) { glRenderbufferStorageOES_t retval = glRenderbufferStorageOES; glRenderbufferStorageOES = f; return retval;}
+    glGetRenderbufferParameterivOES_t set_glGetRenderbufferParameterivOES(glGetRenderbufferParameterivOES_t f) { glGetRenderbufferParameterivOES_t retval = glGetRenderbufferParameterivOES; glGetRenderbufferParameterivOES = f; return retval;}
+    glIsFramebufferOES_t set_glIsFramebufferOES(glIsFramebufferOES_t f) { glIsFramebufferOES_t retval = glIsFramebufferOES; glIsFramebufferOES = f; return retval;}
+    glBindFramebufferOES_t set_glBindFramebufferOES(glBindFramebufferOES_t f) { glBindFramebufferOES_t retval = glBindFramebufferOES; glBindFramebufferOES = f; return retval;}
+    glDeleteFramebuffersOES_t set_glDeleteFramebuffersOES(glDeleteFramebuffersOES_t f) { glDeleteFramebuffersOES_t retval = glDeleteFramebuffersOES; glDeleteFramebuffersOES = f; return retval;}
+    glGenFramebuffersOES_t set_glGenFramebuffersOES(glGenFramebuffersOES_t f) { glGenFramebuffersOES_t retval = glGenFramebuffersOES; glGenFramebuffersOES = f; return retval;}
+    glCheckFramebufferStatusOES_t set_glCheckFramebufferStatusOES(glCheckFramebufferStatusOES_t f) { glCheckFramebufferStatusOES_t retval = glCheckFramebufferStatusOES; glCheckFramebufferStatusOES = f; return retval;}
+    glFramebufferRenderbufferOES_t set_glFramebufferRenderbufferOES(glFramebufferRenderbufferOES_t f) { glFramebufferRenderbufferOES_t retval = glFramebufferRenderbufferOES; glFramebufferRenderbufferOES = f; return retval;}
+    glFramebufferTexture2DOES_t set_glFramebufferTexture2DOES(glFramebufferTexture2DOES_t f) { glFramebufferTexture2DOES_t retval = glFramebufferTexture2DOES; glFramebufferTexture2DOES = f; return retval;}
+    glGetFramebufferAttachmentParameterivOES_t set_glGetFramebufferAttachmentParameterivOES(glGetFramebufferAttachmentParameterivOES_t f) { glGetFramebufferAttachmentParameterivOES_t retval = glGetFramebufferAttachmentParameterivOES; glGetFramebufferAttachmentParameterivOES = f; return retval;}
+    glGenerateMipmapOES_t set_glGenerateMipmapOES(glGenerateMipmapOES_t f) { glGenerateMipmapOES_t retval = glGenerateMipmapOES; glGenerateMipmapOES = f; return retval;}
+    glMapBufferOES_t set_glMapBufferOES(glMapBufferOES_t f) { glMapBufferOES_t retval = glMapBufferOES; glMapBufferOES = f; return retval;}
+    glUnmapBufferOES_t set_glUnmapBufferOES(glUnmapBufferOES_t f) { glUnmapBufferOES_t retval = glUnmapBufferOES; glUnmapBufferOES = f; return retval;}
+    glGetBufferPointervOES_t set_glGetBufferPointervOES(glGetBufferPointervOES_t f) { glGetBufferPointervOES_t retval = glGetBufferPointervOES; glGetBufferPointervOES = f; return retval;}
+    glCurrentPaletteMatrixOES_t set_glCurrentPaletteMatrixOES(glCurrentPaletteMatrixOES_t f) { glCurrentPaletteMatrixOES_t retval = glCurrentPaletteMatrixOES; glCurrentPaletteMatrixOES = f; return retval;}
+    glLoadPaletteFromModelViewMatrixOES_t set_glLoadPaletteFromModelViewMatrixOES(glLoadPaletteFromModelViewMatrixOES_t f) { glLoadPaletteFromModelViewMatrixOES_t retval = glLoadPaletteFromModelViewMatrixOES; glLoadPaletteFromModelViewMatrixOES = f; return retval;}
+    glMatrixIndexPointerOES_t set_glMatrixIndexPointerOES(glMatrixIndexPointerOES_t f) { glMatrixIndexPointerOES_t retval = glMatrixIndexPointerOES; glMatrixIndexPointerOES = f; return retval;}
+    glWeightPointerOES_t set_glWeightPointerOES(glWeightPointerOES_t f) { glWeightPointerOES_t retval = glWeightPointerOES; glWeightPointerOES = f; return retval;}
+    glQueryMatrixxOES_t set_glQueryMatrixxOES(glQueryMatrixxOES_t f) { glQueryMatrixxOES_t retval = glQueryMatrixxOES; glQueryMatrixxOES = f; return retval;}
+    glDepthRangefOES_t set_glDepthRangefOES(glDepthRangefOES_t f) { glDepthRangefOES_t retval = glDepthRangefOES; glDepthRangefOES = f; return retval;}
+    glFrustumfOES_t set_glFrustumfOES(glFrustumfOES_t f) { glFrustumfOES_t retval = glFrustumfOES; glFrustumfOES = f; return retval;}
+    glOrthofOES_t set_glOrthofOES(glOrthofOES_t f) { glOrthofOES_t retval = glOrthofOES; glOrthofOES = f; return retval;}
+    glClipPlanefOES_t set_glClipPlanefOES(glClipPlanefOES_t f) { glClipPlanefOES_t retval = glClipPlanefOES; glClipPlanefOES = f; return retval;}
+    glGetClipPlanefOES_t set_glGetClipPlanefOES(glGetClipPlanefOES_t f) { glGetClipPlanefOES_t retval = glGetClipPlanefOES; glGetClipPlanefOES = f; return retval;}
+    glClearDepthfOES_t set_glClearDepthfOES(glClearDepthfOES_t f) { glClearDepthfOES_t retval = glClearDepthfOES; glClearDepthfOES = f; return retval;}
+    glTexGenfOES_t set_glTexGenfOES(glTexGenfOES_t f) { glTexGenfOES_t retval = glTexGenfOES; glTexGenfOES = f; return retval;}
+    glTexGenfvOES_t set_glTexGenfvOES(glTexGenfvOES_t f) { glTexGenfvOES_t retval = glTexGenfvOES; glTexGenfvOES = f; return retval;}
+    glTexGeniOES_t set_glTexGeniOES(glTexGeniOES_t f) { glTexGeniOES_t retval = glTexGeniOES; glTexGeniOES = f; return retval;}
+    glTexGenivOES_t set_glTexGenivOES(glTexGenivOES_t f) { glTexGenivOES_t retval = glTexGenivOES; glTexGenivOES = f; return retval;}
+    glTexGenxOES_t set_glTexGenxOES(glTexGenxOES_t f) { glTexGenxOES_t retval = glTexGenxOES; glTexGenxOES = f; return retval;}
+    glTexGenxvOES_t set_glTexGenxvOES(glTexGenxvOES_t f) { glTexGenxvOES_t retval = glTexGenxvOES; glTexGenxvOES = f; return retval;}
+    glGetTexGenfvOES_t set_glGetTexGenfvOES(glGetTexGenfvOES_t f) { glGetTexGenfvOES_t retval = glGetTexGenfvOES; glGetTexGenfvOES = f; return retval;}
+    glGetTexGenivOES_t set_glGetTexGenivOES(glGetTexGenivOES_t f) { glGetTexGenivOES_t retval = glGetTexGenivOES; glGetTexGenivOES = f; return retval;}
+    glGetTexGenxvOES_t set_glGetTexGenxvOES(glGetTexGenxvOES_t f) { glGetTexGenxvOES_t retval = glGetTexGenxvOES; glGetTexGenxvOES = f; return retval;}
+    glBindVertexArrayOES_t set_glBindVertexArrayOES(glBindVertexArrayOES_t f) { glBindVertexArrayOES_t retval = glBindVertexArrayOES; glBindVertexArrayOES = f; return retval;}
+    glDeleteVertexArraysOES_t set_glDeleteVertexArraysOES(glDeleteVertexArraysOES_t f) { glDeleteVertexArraysOES_t retval = glDeleteVertexArraysOES; glDeleteVertexArraysOES = f; return retval;}
+    glGenVertexArraysOES_t set_glGenVertexArraysOES(glGenVertexArraysOES_t f) { glGenVertexArraysOES_t retval = glGenVertexArraysOES; glGenVertexArraysOES = f; return retval;}
+    glIsVertexArrayOES_t set_glIsVertexArrayOES(glIsVertexArrayOES_t f) { glIsVertexArrayOES_t retval = glIsVertexArrayOES; glIsVertexArrayOES = f; return retval;}
+    glDiscardFramebufferEXT_t set_glDiscardFramebufferEXT(glDiscardFramebufferEXT_t f) { glDiscardFramebufferEXT_t retval = glDiscardFramebufferEXT; glDiscardFramebufferEXT = f; return retval;}
+    glMultiDrawArraysEXT_t set_glMultiDrawArraysEXT(glMultiDrawArraysEXT_t f) { glMultiDrawArraysEXT_t retval = glMultiDrawArraysEXT; glMultiDrawArraysEXT = f; return retval;}
+    glMultiDrawElementsEXT_t set_glMultiDrawElementsEXT(glMultiDrawElementsEXT_t f) { glMultiDrawElementsEXT_t retval = glMultiDrawElementsEXT; glMultiDrawElementsEXT = f; return retval;}
+    glClipPlanefIMG_t set_glClipPlanefIMG(glClipPlanefIMG_t f) { glClipPlanefIMG_t retval = glClipPlanefIMG; glClipPlanefIMG = f; return retval;}
+    glClipPlanexIMG_t set_glClipPlanexIMG(glClipPlanexIMG_t f) { glClipPlanexIMG_t retval = glClipPlanexIMG; glClipPlanexIMG = f; return retval;}
+    glRenderbufferStorageMultisampleIMG_t set_glRenderbufferStorageMultisampleIMG(glRenderbufferStorageMultisampleIMG_t f) { glRenderbufferStorageMultisampleIMG_t retval = glRenderbufferStorageMultisampleIMG; glRenderbufferStorageMultisampleIMG = f; return retval;}
+    glFramebufferTexture2DMultisampleIMG_t set_glFramebufferTexture2DMultisampleIMG(glFramebufferTexture2DMultisampleIMG_t f) { glFramebufferTexture2DMultisampleIMG_t retval = glFramebufferTexture2DMultisampleIMG; glFramebufferTexture2DMultisampleIMG = f; return retval;}
+    glDeleteFencesNV_t set_glDeleteFencesNV(glDeleteFencesNV_t f) { glDeleteFencesNV_t retval = glDeleteFencesNV; glDeleteFencesNV = f; return retval;}
+    glGenFencesNV_t set_glGenFencesNV(glGenFencesNV_t f) { glGenFencesNV_t retval = glGenFencesNV; glGenFencesNV = f; return retval;}
+    glIsFenceNV_t set_glIsFenceNV(glIsFenceNV_t f) { glIsFenceNV_t retval = glIsFenceNV; glIsFenceNV = f; return retval;}
+    glTestFenceNV_t set_glTestFenceNV(glTestFenceNV_t f) { glTestFenceNV_t retval = glTestFenceNV; glTestFenceNV = f; return retval;}
+    glGetFenceivNV_t set_glGetFenceivNV(glGetFenceivNV_t f) { glGetFenceivNV_t retval = glGetFenceivNV; glGetFenceivNV = f; return retval;}
+    glFinishFenceNV_t set_glFinishFenceNV(glFinishFenceNV_t f) { glFinishFenceNV_t retval = glFinishFenceNV; glFinishFenceNV = f; return retval;}
+    glSetFenceNV_t set_glSetFenceNV(glSetFenceNV_t f) { glSetFenceNV_t retval = glSetFenceNV; glSetFenceNV = f; return retval;}
+    glGetDriverControlsQCOM_t set_glGetDriverControlsQCOM(glGetDriverControlsQCOM_t f) { glGetDriverControlsQCOM_t retval = glGetDriverControlsQCOM; glGetDriverControlsQCOM = f; return retval;}
+    glGetDriverControlStringQCOM_t set_glGetDriverControlStringQCOM(glGetDriverControlStringQCOM_t f) { glGetDriverControlStringQCOM_t retval = glGetDriverControlStringQCOM; glGetDriverControlStringQCOM = f; return retval;}
+    glEnableDriverControlQCOM_t set_glEnableDriverControlQCOM(glEnableDriverControlQCOM_t f) { glEnableDriverControlQCOM_t retval = glEnableDriverControlQCOM; glEnableDriverControlQCOM = f; return retval;}
+    glDisableDriverControlQCOM_t set_glDisableDriverControlQCOM(glDisableDriverControlQCOM_t f) { glDisableDriverControlQCOM_t retval = glDisableDriverControlQCOM; glDisableDriverControlQCOM = f; return retval;}
+    glExtGetTexturesQCOM_t set_glExtGetTexturesQCOM(glExtGetTexturesQCOM_t f) { glExtGetTexturesQCOM_t retval = glExtGetTexturesQCOM; glExtGetTexturesQCOM = f; return retval;}
+    glExtGetBuffersQCOM_t set_glExtGetBuffersQCOM(glExtGetBuffersQCOM_t f) { glExtGetBuffersQCOM_t retval = glExtGetBuffersQCOM; glExtGetBuffersQCOM = f; return retval;}
+    glExtGetRenderbuffersQCOM_t set_glExtGetRenderbuffersQCOM(glExtGetRenderbuffersQCOM_t f) { glExtGetRenderbuffersQCOM_t retval = glExtGetRenderbuffersQCOM; glExtGetRenderbuffersQCOM = f; return retval;}
+    glExtGetFramebuffersQCOM_t set_glExtGetFramebuffersQCOM(glExtGetFramebuffersQCOM_t f) { glExtGetFramebuffersQCOM_t retval = glExtGetFramebuffersQCOM; glExtGetFramebuffersQCOM = f; return retval;}
+    glExtGetTexLevelParameterivQCOM_t set_glExtGetTexLevelParameterivQCOM(glExtGetTexLevelParameterivQCOM_t f) { glExtGetTexLevelParameterivQCOM_t retval = glExtGetTexLevelParameterivQCOM; glExtGetTexLevelParameterivQCOM = f; return retval;}
+    glExtTexObjectStateOverrideiQCOM_t set_glExtTexObjectStateOverrideiQCOM(glExtTexObjectStateOverrideiQCOM_t f) { glExtTexObjectStateOverrideiQCOM_t retval = glExtTexObjectStateOverrideiQCOM; glExtTexObjectStateOverrideiQCOM = f; return retval;}
+    glExtGetTexSubImageQCOM_t set_glExtGetTexSubImageQCOM(glExtGetTexSubImageQCOM_t f) { glExtGetTexSubImageQCOM_t retval = glExtGetTexSubImageQCOM; glExtGetTexSubImageQCOM = f; return retval;}
+    glExtGetBufferPointervQCOM_t set_glExtGetBufferPointervQCOM(glExtGetBufferPointervQCOM_t f) { glExtGetBufferPointervQCOM_t retval = glExtGetBufferPointervQCOM; glExtGetBufferPointervQCOM = f; return retval;}
+    glExtGetShadersQCOM_t set_glExtGetShadersQCOM(glExtGetShadersQCOM_t f) { glExtGetShadersQCOM_t retval = glExtGetShadersQCOM; glExtGetShadersQCOM = f; return retval;}
+    glExtGetProgramsQCOM_t set_glExtGetProgramsQCOM(glExtGetProgramsQCOM_t f) { glExtGetProgramsQCOM_t retval = glExtGetProgramsQCOM; glExtGetProgramsQCOM = f; return retval;}
+    glExtIsProgramBinaryQCOM_t set_glExtIsProgramBinaryQCOM(glExtIsProgramBinaryQCOM_t f) { glExtIsProgramBinaryQCOM_t retval = glExtIsProgramBinaryQCOM; glExtIsProgramBinaryQCOM = f; return retval;}
+    glExtGetProgramBinarySourceQCOM_t set_glExtGetProgramBinarySourceQCOM(glExtGetProgramBinarySourceQCOM_t f) { glExtGetProgramBinarySourceQCOM_t retval = glExtGetProgramBinarySourceQCOM; glExtGetProgramBinarySourceQCOM = f; return retval;}
+    glStartTilingQCOM_t set_glStartTilingQCOM(glStartTilingQCOM_t f) { glStartTilingQCOM_t retval = glStartTilingQCOM; glStartTilingQCOM = f; return retval;}
+    glEndTilingQCOM_t set_glEndTilingQCOM(glEndTilingQCOM_t f) { glEndTilingQCOM_t retval = glEndTilingQCOM; glEndTilingQCOM = f; return retval;}
+};
+
+gles_dispatch *create_gles_dispatch(void *gles_andorid);
+
+#endif
diff --git a/opengl/tests/gles_android_wrapper/gles_emul.cfg b/opengl/tests/gles_android_wrapper/gles_emul.cfg
new file mode 100644
index 0000000..a837807
--- /dev/null
+++ b/opengl/tests/gles_android_wrapper/gles_emul.cfg
@@ -0,0 +1,7 @@
+angeles
+my-tritex
+org.zeroxlab.benchmark
+com.cooliris.media
+com.polarbit.waveblazerlite
+test-opengl-gl2_basic
+com.trendy.ddapp
diff --git a/opengl/tests/gles_android_wrapper/gles_ftable.h b/opengl/tests/gles_android_wrapper/gles_ftable.h
new file mode 100644
index 0000000..1895b18
--- /dev/null
+++ b/opengl/tests/gles_android_wrapper/gles_ftable.h
@@ -0,0 +1,292 @@
+/*
+* Copyright (C) 2011 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.
+*/
+static struct _gles_funcs_by_name {
+    const char *name;
+    void *proc;
+} gles_funcs_by_name[] = {
+    {"glAlphaFunc", (void *)glAlphaFunc},
+    {"glClearColor", (void *)glClearColor},
+    {"glClearDepthf", (void *)glClearDepthf},
+    {"glClipPlanef", (void *)glClipPlanef},
+    {"glColor4f", (void *)glColor4f},
+    {"glDepthRangef", (void *)glDepthRangef},
+    {"glFogf", (void *)glFogf},
+    {"glFogfv", (void *)glFogfv},
+    {"glFrustumf", (void *)glFrustumf},
+    {"glGetClipPlanef", (void *)glGetClipPlanef},
+    {"glGetFloatv", (void *)glGetFloatv},
+    {"glGetLightfv", (void *)glGetLightfv},
+    {"glGetMaterialfv", (void *)glGetMaterialfv},
+    {"glGetTexEnvfv", (void *)glGetTexEnvfv},
+    {"glGetTexParameterfv", (void *)glGetTexParameterfv},
+    {"glLightModelf", (void *)glLightModelf},
+    {"glLightModelfv", (void *)glLightModelfv},
+    {"glLightf", (void *)glLightf},
+    {"glLightfv", (void *)glLightfv},
+    {"glLineWidth", (void *)glLineWidth},
+    {"glLoadMatrixf", (void *)glLoadMatrixf},
+    {"glMaterialf", (void *)glMaterialf},
+    {"glMaterialfv", (void *)glMaterialfv},
+    {"glMultMatrixf", (void *)glMultMatrixf},
+    {"glMultiTexCoord4f", (void *)glMultiTexCoord4f},
+    {"glNormal3f", (void *)glNormal3f},
+    {"glOrthof", (void *)glOrthof},
+    {"glPointParameterf", (void *)glPointParameterf},
+    {"glPointParameterfv", (void *)glPointParameterfv},
+    {"glPointSize", (void *)glPointSize},
+    {"glPolygonOffset", (void *)glPolygonOffset},
+    {"glRotatef", (void *)glRotatef},
+    {"glScalef", (void *)glScalef},
+    {"glTexEnvf", (void *)glTexEnvf},
+    {"glTexEnvfv", (void *)glTexEnvfv},
+    {"glTexParameterf", (void *)glTexParameterf},
+    {"glTexParameterfv", (void *)glTexParameterfv},
+    {"glTranslatef", (void *)glTranslatef},
+    {"glActiveTexture", (void *)glActiveTexture},
+    {"glAlphaFuncx", (void *)glAlphaFuncx},
+    {"glBindBuffer", (void *)glBindBuffer},
+    {"glBindTexture", (void *)glBindTexture},
+    {"glBlendFunc", (void *)glBlendFunc},
+    {"glBufferData", (void *)glBufferData},
+    {"glBufferSubData", (void *)glBufferSubData},
+    {"glClear", (void *)glClear},
+    {"glClearColorx", (void *)glClearColorx},
+    {"glClearDepthx", (void *)glClearDepthx},
+    {"glClearStencil", (void *)glClearStencil},
+    {"glClientActiveTexture", (void *)glClientActiveTexture},
+    {"glClipPlanex", (void *)glClipPlanex},
+    {"glColor4ub", (void *)glColor4ub},
+    {"glColor4x", (void *)glColor4x},
+    {"glColorMask", (void *)glColorMask},
+    {"glColorPointer", (void *)glColorPointer},
+    {"glCompressedTexImage2D", (void *)glCompressedTexImage2D},
+    {"glCompressedTexSubImage2D", (void *)glCompressedTexSubImage2D},
+    {"glCopyTexImage2D", (void *)glCopyTexImage2D},
+    {"glCopyTexSubImage2D", (void *)glCopyTexSubImage2D},
+    {"glCullFace", (void *)glCullFace},
+    {"glDeleteBuffers", (void *)glDeleteBuffers},
+    {"glDeleteTextures", (void *)glDeleteTextures},
+    {"glDepthFunc", (void *)glDepthFunc},
+    {"glDepthMask", (void *)glDepthMask},
+    {"glDepthRangex", (void *)glDepthRangex},
+    {"glDisable", (void *)glDisable},
+    {"glDisableClientState", (void *)glDisableClientState},
+    {"glDrawArrays", (void *)glDrawArrays},
+    {"glDrawElements", (void *)glDrawElements},
+    {"glEnable", (void *)glEnable},
+    {"glEnableClientState", (void *)glEnableClientState},
+    {"glFinish", (void *)glFinish},
+    {"glFlush", (void *)glFlush},
+    {"glFogx", (void *)glFogx},
+    {"glFogxv", (void *)glFogxv},
+    {"glFrontFace", (void *)glFrontFace},
+    {"glFrustumx", (void *)glFrustumx},
+    {"glGetBooleanv", (void *)glGetBooleanv},
+    {"glGetBufferParameteriv", (void *)glGetBufferParameteriv},
+    {"glGetClipPlanex", (void *)glGetClipPlanex},
+    {"glGenBuffers", (void *)glGenBuffers},
+    {"glGenTextures", (void *)glGenTextures},
+    {"glGetError", (void *)glGetError},
+    {"glGetFixedv", (void *)glGetFixedv},
+    {"glGetIntegerv", (void *)glGetIntegerv},
+    {"glGetLightxv", (void *)glGetLightxv},
+    {"glGetMaterialxv", (void *)glGetMaterialxv},
+    {"glGetPointerv", (void *)glGetPointerv},
+    {"glGetString", (void *)glGetString},
+    {"glGetTexEnviv", (void *)glGetTexEnviv},
+    {"glGetTexEnvxv", (void *)glGetTexEnvxv},
+    {"glGetTexParameteriv", (void *)glGetTexParameteriv},
+    {"glGetTexParameterxv", (void *)glGetTexParameterxv},
+    {"glHint", (void *)glHint},
+    {"glIsBuffer", (void *)glIsBuffer},
+    {"glIsEnabled", (void *)glIsEnabled},
+    {"glIsTexture", (void *)glIsTexture},
+    {"glLightModelx", (void *)glLightModelx},
+    {"glLightModelxv", (void *)glLightModelxv},
+    {"glLightx", (void *)glLightx},
+    {"glLightxv", (void *)glLightxv},
+    {"glLineWidthx", (void *)glLineWidthx},
+    {"glLoadIdentity", (void *)glLoadIdentity},
+    {"glLoadMatrixx", (void *)glLoadMatrixx},
+    {"glLogicOp", (void *)glLogicOp},
+    {"glMaterialx", (void *)glMaterialx},
+    {"glMaterialxv", (void *)glMaterialxv},
+    {"glMatrixMode", (void *)glMatrixMode},
+    {"glMultMatrixx", (void *)glMultMatrixx},
+    {"glMultiTexCoord4x", (void *)glMultiTexCoord4x},
+    {"glNormal3x", (void *)glNormal3x},
+    {"glNormalPointer", (void *)glNormalPointer},
+    {"glOrthox", (void *)glOrthox},
+    {"glPixelStorei", (void *)glPixelStorei},
+    {"glPointParameterx", (void *)glPointParameterx},
+    {"glPointParameterxv", (void *)glPointParameterxv},
+    {"glPointSizex", (void *)glPointSizex},
+    {"glPolygonOffsetx", (void *)glPolygonOffsetx},
+    {"glPopMatrix", (void *)glPopMatrix},
+    {"glPushMatrix", (void *)glPushMatrix},
+    {"glReadPixels", (void *)glReadPixels},
+    {"glRotatex", (void *)glRotatex},
+    {"glSampleCoverage", (void *)glSampleCoverage},
+    {"glSampleCoveragex", (void *)glSampleCoveragex},
+    {"glScalex", (void *)glScalex},
+    {"glScissor", (void *)glScissor},
+    {"glShadeModel", (void *)glShadeModel},
+    {"glStencilFunc", (void *)glStencilFunc},
+    {"glStencilMask", (void *)glStencilMask},
+    {"glStencilOp", (void *)glStencilOp},
+    {"glTexCoordPointer", (void *)glTexCoordPointer},
+    {"glTexEnvi", (void *)glTexEnvi},
+    {"glTexEnvx", (void *)glTexEnvx},
+    {"glTexEnviv", (void *)glTexEnviv},
+    {"glTexEnvxv", (void *)glTexEnvxv},
+    {"glTexImage2D", (void *)glTexImage2D},
+    {"glTexParameteri", (void *)glTexParameteri},
+    {"glTexParameterx", (void *)glTexParameterx},
+    {"glTexParameteriv", (void *)glTexParameteriv},
+    {"glTexParameterxv", (void *)glTexParameterxv},
+    {"glTexSubImage2D", (void *)glTexSubImage2D},
+    {"glTranslatex", (void *)glTranslatex},
+    {"glVertexPointer", (void *)glVertexPointer},
+    {"glViewport", (void *)glViewport},
+    {"glPointSizePointerOES", (void *)glPointSizePointerOES},
+    {"glBlendEquationSeparateOES", (void *)glBlendEquationSeparateOES},
+    {"glBlendFuncSeparateOES", (void *)glBlendFuncSeparateOES},
+    {"glBlendEquationOES", (void *)glBlendEquationOES},
+    {"glDrawTexsOES", (void *)glDrawTexsOES},
+    {"glDrawTexiOES", (void *)glDrawTexiOES},
+    {"glDrawTexxOES", (void *)glDrawTexxOES},
+    {"glDrawTexsvOES", (void *)glDrawTexsvOES},
+    {"glDrawTexivOES", (void *)glDrawTexivOES},
+    {"glDrawTexxvOES", (void *)glDrawTexxvOES},
+    {"glDrawTexfOES", (void *)glDrawTexfOES},
+    {"glDrawTexfvOES", (void *)glDrawTexfvOES},
+    {"glEGLImageTargetTexture2DOES", (void *)glEGLImageTargetTexture2DOES},
+    {"glEGLImageTargetRenderbufferStorageOES", (void *)glEGLImageTargetRenderbufferStorageOES},
+    {"glAlphaFuncxOES", (void *)glAlphaFuncxOES},
+    {"glClearColorxOES", (void *)glClearColorxOES},
+    {"glClearDepthxOES", (void *)glClearDepthxOES},
+    {"glClipPlanexOES", (void *)glClipPlanexOES},
+    {"glColor4xOES", (void *)glColor4xOES},
+    {"glDepthRangexOES", (void *)glDepthRangexOES},
+    {"glFogxOES", (void *)glFogxOES},
+    {"glFogxvOES", (void *)glFogxvOES},
+    {"glFrustumxOES", (void *)glFrustumxOES},
+    {"glGetClipPlanexOES", (void *)glGetClipPlanexOES},
+    {"glGetFixedvOES", (void *)glGetFixedvOES},
+    {"glGetLightxvOES", (void *)glGetLightxvOES},
+    {"glGetMaterialxvOES", (void *)glGetMaterialxvOES},
+    {"glGetTexEnvxvOES", (void *)glGetTexEnvxvOES},
+    {"glGetTexParameterxvOES", (void *)glGetTexParameterxvOES},
+    {"glLightModelxOES", (void *)glLightModelxOES},
+    {"glLightModelxvOES", (void *)glLightModelxvOES},
+    {"glLightxOES", (void *)glLightxOES},
+    {"glLightxvOES", (void *)glLightxvOES},
+    {"glLineWidthxOES", (void *)glLineWidthxOES},
+    {"glLoadMatrixxOES", (void *)glLoadMatrixxOES},
+    {"glMaterialxOES", (void *)glMaterialxOES},
+    {"glMaterialxvOES", (void *)glMaterialxvOES},
+    {"glMultMatrixxOES", (void *)glMultMatrixxOES},
+    {"glMultiTexCoord4xOES", (void *)glMultiTexCoord4xOES},
+    {"glNormal3xOES", (void *)glNormal3xOES},
+    {"glOrthoxOES", (void *)glOrthoxOES},
+    {"glPointParameterxOES", (void *)glPointParameterxOES},
+    {"glPointParameterxvOES", (void *)glPointParameterxvOES},
+    {"glPointSizexOES", (void *)glPointSizexOES},
+    {"glPolygonOffsetxOES", (void *)glPolygonOffsetxOES},
+    {"glRotatexOES", (void *)glRotatexOES},
+    {"glSampleCoveragexOES", (void *)glSampleCoveragexOES},
+    {"glScalexOES", (void *)glScalexOES},
+    {"glTexEnvxOES", (void *)glTexEnvxOES},
+    {"glTexEnvxvOES", (void *)glTexEnvxvOES},
+    {"glTexParameterxOES", (void *)glTexParameterxOES},
+    {"glTexParameterxvOES", (void *)glTexParameterxvOES},
+    {"glTranslatexOES", (void *)glTranslatexOES},
+    {"glIsRenderbufferOES", (void *)glIsRenderbufferOES},
+    {"glBindRenderbufferOES", (void *)glBindRenderbufferOES},
+    {"glDeleteRenderbuffersOES", (void *)glDeleteRenderbuffersOES},
+    {"glGenRenderbuffersOES", (void *)glGenRenderbuffersOES},
+    {"glRenderbufferStorageOES", (void *)glRenderbufferStorageOES},
+    {"glGetRenderbufferParameterivOES", (void *)glGetRenderbufferParameterivOES},
+    {"glIsFramebufferOES", (void *)glIsFramebufferOES},
+    {"glBindFramebufferOES", (void *)glBindFramebufferOES},
+    {"glDeleteFramebuffersOES", (void *)glDeleteFramebuffersOES},
+    {"glGenFramebuffersOES", (void *)glGenFramebuffersOES},
+    {"glCheckFramebufferStatusOES", (void *)glCheckFramebufferStatusOES},
+    {"glFramebufferRenderbufferOES", (void *)glFramebufferRenderbufferOES},
+    {"glFramebufferTexture2DOES", (void *)glFramebufferTexture2DOES},
+    {"glGetFramebufferAttachmentParameterivOES", (void *)glGetFramebufferAttachmentParameterivOES},
+    {"glGenerateMipmapOES", (void *)glGenerateMipmapOES},
+    {"glMapBufferOES", (void *)glMapBufferOES},
+    {"glUnmapBufferOES", (void *)glUnmapBufferOES},
+    {"glGetBufferPointervOES", (void *)glGetBufferPointervOES},
+    {"glCurrentPaletteMatrixOES", (void *)glCurrentPaletteMatrixOES},
+    {"glLoadPaletteFromModelViewMatrixOES", (void *)glLoadPaletteFromModelViewMatrixOES},
+    {"glMatrixIndexPointerOES", (void *)glMatrixIndexPointerOES},
+    {"glWeightPointerOES", (void *)glWeightPointerOES},
+    {"glQueryMatrixxOES", (void *)glQueryMatrixxOES},
+    {"glDepthRangefOES", (void *)glDepthRangefOES},
+    {"glFrustumfOES", (void *)glFrustumfOES},
+    {"glOrthofOES", (void *)glOrthofOES},
+    {"glClipPlanefOES", (void *)glClipPlanefOES},
+    {"glGetClipPlanefOES", (void *)glGetClipPlanefOES},
+    {"glClearDepthfOES", (void *)glClearDepthfOES},
+    {"glTexGenfOES", (void *)glTexGenfOES},
+    {"glTexGenfvOES", (void *)glTexGenfvOES},
+    {"glTexGeniOES", (void *)glTexGeniOES},
+    {"glTexGenivOES", (void *)glTexGenivOES},
+    {"glTexGenxOES", (void *)glTexGenxOES},
+    {"glTexGenxvOES", (void *)glTexGenxvOES},
+    {"glGetTexGenfvOES", (void *)glGetTexGenfvOES},
+    {"glGetTexGenivOES", (void *)glGetTexGenivOES},
+    {"glGetTexGenxvOES", (void *)glGetTexGenxvOES},
+    {"glBindVertexArrayOES", (void *)glBindVertexArrayOES},
+    {"glDeleteVertexArraysOES", (void *)glDeleteVertexArraysOES},
+    {"glGenVertexArraysOES", (void *)glGenVertexArraysOES},
+    {"glIsVertexArrayOES", (void *)glIsVertexArrayOES},
+    {"glDiscardFramebufferEXT", (void *)glDiscardFramebufferEXT},
+    {"glMultiDrawArraysEXT", (void *)glMultiDrawArraysEXT},
+    {"glMultiDrawElementsEXT", (void *)glMultiDrawElementsEXT},
+    {"glClipPlanefIMG", (void *)glClipPlanefIMG},
+    {"glClipPlanexIMG", (void *)glClipPlanexIMG},
+    {"glRenderbufferStorageMultisampleIMG", (void *)glRenderbufferStorageMultisampleIMG},
+    {"glFramebufferTexture2DMultisampleIMG", (void *)glFramebufferTexture2DMultisampleIMG},
+    {"glDeleteFencesNV", (void *)glDeleteFencesNV},
+    {"glGenFencesNV", (void *)glGenFencesNV},
+    {"glIsFenceNV", (void *)glIsFenceNV},
+    {"glTestFenceNV", (void *)glTestFenceNV},
+    {"glGetFenceivNV", (void *)glGetFenceivNV},
+    {"glFinishFenceNV", (void *)glFinishFenceNV},
+    {"glSetFenceNV", (void *)glSetFenceNV},
+    {"glGetDriverControlsQCOM", (void *)glGetDriverControlsQCOM},
+    {"glGetDriverControlStringQCOM", (void *)glGetDriverControlStringQCOM},
+    {"glEnableDriverControlQCOM", (void *)glEnableDriverControlQCOM},
+    {"glDisableDriverControlQCOM", (void *)glDisableDriverControlQCOM},
+    {"glExtGetTexturesQCOM", (void *)glExtGetTexturesQCOM},
+    {"glExtGetBuffersQCOM", (void *)glExtGetBuffersQCOM},
+    {"glExtGetRenderbuffersQCOM", (void *)glExtGetRenderbuffersQCOM},
+    {"glExtGetFramebuffersQCOM", (void *)glExtGetFramebuffersQCOM},
+    {"glExtGetTexLevelParameterivQCOM", (void *)glExtGetTexLevelParameterivQCOM},
+    {"glExtTexObjectStateOverrideiQCOM", (void *)glExtTexObjectStateOverrideiQCOM},
+    {"glExtGetTexSubImageQCOM", (void *)glExtGetTexSubImageQCOM},
+    {"glExtGetBufferPointervQCOM", (void *)glExtGetBufferPointervQCOM},
+    {"glExtGetShadersQCOM", (void *)glExtGetShadersQCOM},
+    {"glExtGetProgramsQCOM", (void *)glExtGetProgramsQCOM},
+    {"glExtIsProgramBinaryQCOM", (void *)glExtIsProgramBinaryQCOM},
+    {"glExtGetProgramBinarySourceQCOM", (void *)glExtGetProgramBinarySourceQCOM},
+    {"glStartTilingQCOM", (void *)glStartTilingQCOM},
+    {"glEndTilingQCOM", (void *)glEndTilingQCOM}
+};
+static int gles_num_funcs = sizeof(gles_funcs_by_name) / sizeof(struct _gles_funcs_by_name);
diff --git a/opengl/tests/gles_android_wrapper/gles_proc.h b/opengl/tests/gles_android_wrapper/gles_proc.h
new file mode 100644
index 0000000..afd94b9
--- /dev/null
+++ b/opengl/tests/gles_android_wrapper/gles_proc.h
@@ -0,0 +1,296 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#ifndef _GLES_PROC_H
+#define _GLES_PROC_H
+
+#include <GLES/gl.h>
+#define GL_GLEXT_PROTOTYPES
+#include <GLES/glext.h>
+
+typedef void (* glAlphaFunc_t) (GLenum, GLclampf);
+typedef void (* glClearColor_t) (GLclampf, GLclampf, GLclampf, GLclampf);
+typedef void (* glClearDepthf_t) (GLclampf);
+typedef void (* glClipPlanef_t) (GLenum, const GLfloat*);
+typedef void (* glColor4f_t) (GLfloat, GLfloat, GLfloat, GLfloat);
+typedef void (* glDepthRangef_t) (GLclampf, GLclampf);
+typedef void (* glFogf_t) (GLenum, GLfloat);
+typedef void (* glFogfv_t) (GLenum, const GLfloat*);
+typedef void (* glFrustumf_t) (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+typedef void (* glGetClipPlanef_t) (GLenum, GLfloat*);
+typedef void (* glGetFloatv_t) (GLenum, GLfloat*);
+typedef void (* glGetLightfv_t) (GLenum, GLenum, GLfloat*);
+typedef void (* glGetMaterialfv_t) (GLenum, GLenum, GLfloat*);
+typedef void (* glGetTexEnvfv_t) (GLenum, GLenum, GLfloat*);
+typedef void (* glGetTexParameterfv_t) (GLenum, GLenum, GLfloat*);
+typedef void (* glLightModelf_t) (GLenum, GLfloat);
+typedef void (* glLightModelfv_t) (GLenum, const GLfloat*);
+typedef void (* glLightf_t) (GLenum, GLenum, GLfloat);
+typedef void (* glLightfv_t) (GLenum, GLenum, const GLfloat*);
+typedef void (* glLineWidth_t) (GLfloat);
+typedef void (* glLoadMatrixf_t) (const GLfloat*);
+typedef void (* glMaterialf_t) (GLenum, GLenum, GLfloat);
+typedef void (* glMaterialfv_t) (GLenum, GLenum, const GLfloat*);
+typedef void (* glMultMatrixf_t) (const GLfloat*);
+typedef void (* glMultiTexCoord4f_t) (GLenum, GLfloat, GLfloat, GLfloat, GLfloat);
+typedef void (* glNormal3f_t) (GLfloat, GLfloat, GLfloat);
+typedef void (* glOrthof_t) (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+typedef void (* glPointParameterf_t) (GLenum, GLfloat);
+typedef void (* glPointParameterfv_t) (GLenum, const GLfloat*);
+typedef void (* glPointSize_t) (GLfloat);
+typedef void (* glPolygonOffset_t) (GLfloat, GLfloat);
+typedef void (* glRotatef_t) (GLfloat, GLfloat, GLfloat, GLfloat);
+typedef void (* glScalef_t) (GLfloat, GLfloat, GLfloat);
+typedef void (* glTexEnvf_t) (GLenum, GLenum, GLfloat);
+typedef void (* glTexEnvfv_t) (GLenum, GLenum, const GLfloat*);
+typedef void (* glTexParameterf_t) (GLenum, GLenum, GLfloat);
+typedef void (* glTexParameterfv_t) (GLenum, GLenum, const GLfloat*);
+typedef void (* glTranslatef_t) (GLfloat, GLfloat, GLfloat);
+typedef void (* glActiveTexture_t) (GLenum);
+typedef void (* glAlphaFuncx_t) (GLenum, GLclampx);
+typedef void (* glBindBuffer_t) (GLenum, GLuint);
+typedef void (* glBindTexture_t) (GLenum, GLuint);
+typedef void (* glBlendFunc_t) (GLenum, GLenum);
+typedef void (* glBufferData_t) (GLenum, GLsizeiptr, const GLvoid*, GLenum);
+typedef void (* glBufferSubData_t) (GLenum, GLintptr, GLsizeiptr, const GLvoid*);
+typedef void (* glClear_t) (GLbitfield);
+typedef void (* glClearColorx_t) (GLclampx, GLclampx, GLclampx, GLclampx);
+typedef void (* glClearDepthx_t) (GLclampx);
+typedef void (* glClearStencil_t) (GLint);
+typedef void (* glClientActiveTexture_t) (GLenum);
+typedef void (* glClipPlanex_t) (GLenum, const GLfixed*);
+typedef void (* glColor4ub_t) (GLubyte, GLubyte, GLubyte, GLubyte);
+typedef void (* glColor4x_t) (GLfixed, GLfixed, GLfixed, GLfixed);
+typedef void (* glColorMask_t) (GLboolean, GLboolean, GLboolean, GLboolean);
+typedef void (* glColorPointer_t) (GLint, GLenum, GLsizei, const GLvoid*);
+typedef void (* glCompressedTexImage2D_t) (GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid*);
+typedef void (* glCompressedTexSubImage2D_t) (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid*);
+typedef void (* glCopyTexImage2D_t) (GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint);
+typedef void (* glCopyTexSubImage2D_t) (GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei);
+typedef void (* glCullFace_t) (GLenum);
+typedef void (* glDeleteBuffers_t) (GLsizei, const GLuint*);
+typedef void (* glDeleteTextures_t) (GLsizei, const GLuint*);
+typedef void (* glDepthFunc_t) (GLenum);
+typedef void (* glDepthMask_t) (GLboolean);
+typedef void (* glDepthRangex_t) (GLclampx, GLclampx);
+typedef void (* glDisable_t) (GLenum);
+typedef void (* glDisableClientState_t) (GLenum);
+typedef void (* glDrawArrays_t) (GLenum, GLint, GLsizei);
+typedef void (* glDrawElements_t) (GLenum, GLsizei, GLenum, const GLvoid*);
+typedef void (* glEnable_t) (GLenum);
+typedef void (* glEnableClientState_t) (GLenum);
+typedef void (* glFinish_t) ();
+typedef void (* glFlush_t) ();
+typedef void (* glFogx_t) (GLenum, GLfixed);
+typedef void (* glFogxv_t) (GLenum, const GLfixed*);
+typedef void (* glFrontFace_t) (GLenum);
+typedef void (* glFrustumx_t) (GLfixed, GLfixed, GLfixed, GLfixed, GLfixed, GLfixed);
+typedef void (* glGetBooleanv_t) (GLenum, GLboolean*);
+typedef void (* glGetBufferParameteriv_t) (GLenum, GLenum, GLint*);
+typedef void (* glGetClipPlanex_t) (GLenum, GLfixed*);
+typedef void (* glGenBuffers_t) (GLsizei, GLuint*);
+typedef void (* glGenTextures_t) (GLsizei, GLuint*);
+typedef GLenum (* glGetError_t) ();
+typedef void (* glGetFixedv_t) (GLenum, GLfixed*);
+typedef void (* glGetIntegerv_t) (GLenum, GLint*);
+typedef void (* glGetLightxv_t) (GLenum, GLenum, GLfixed*);
+typedef void (* glGetMaterialxv_t) (GLenum, GLenum, GLfixed*);
+typedef void (* glGetPointerv_t) (GLenum, GLvoid**);
+typedef const GLubyte* (* glGetString_t) (GLenum);
+typedef void (* glGetTexEnviv_t) (GLenum, GLenum, GLint*);
+typedef void (* glGetTexEnvxv_t) (GLenum, GLenum, GLfixed*);
+typedef void (* glGetTexParameteriv_t) (GLenum, GLenum, GLint*);
+typedef void (* glGetTexParameterxv_t) (GLenum, GLenum, GLfixed*);
+typedef void (* glHint_t) (GLenum, GLenum);
+typedef GLboolean (* glIsBuffer_t) (GLuint);
+typedef GLboolean (* glIsEnabled_t) (GLenum);
+typedef GLboolean (* glIsTexture_t) (GLuint);
+typedef void (* glLightModelx_t) (GLenum, GLfixed);
+typedef void (* glLightModelxv_t) (GLenum, const GLfixed*);
+typedef void (* glLightx_t) (GLenum, GLenum, GLfixed);
+typedef void (* glLightxv_t) (GLenum, GLenum, const GLfixed*);
+typedef void (* glLineWidthx_t) (GLfixed);
+typedef void (* glLoadIdentity_t) ();
+typedef void (* glLoadMatrixx_t) (const GLfixed*);
+typedef void (* glLogicOp_t) (GLenum);
+typedef void (* glMaterialx_t) (GLenum, GLenum, GLfixed);
+typedef void (* glMaterialxv_t) (GLenum, GLenum, const GLfixed*);
+typedef void (* glMatrixMode_t) (GLenum);
+typedef void (* glMultMatrixx_t) (const GLfixed*);
+typedef void (* glMultiTexCoord4x_t) (GLenum, GLfixed, GLfixed, GLfixed, GLfixed);
+typedef void (* glNormal3x_t) (GLfixed, GLfixed, GLfixed);
+typedef void (* glNormalPointer_t) (GLenum, GLsizei, const GLvoid*);
+typedef void (* glOrthox_t) (GLfixed, GLfixed, GLfixed, GLfixed, GLfixed, GLfixed);
+typedef void (* glPixelStorei_t) (GLenum, GLint);
+typedef void (* glPointParameterx_t) (GLenum, GLfixed);
+typedef void (* glPointParameterxv_t) (GLenum, const GLfixed*);
+typedef void (* glPointSizex_t) (GLfixed);
+typedef void (* glPolygonOffsetx_t) (GLfixed, GLfixed);
+typedef void (* glPopMatrix_t) ();
+typedef void (* glPushMatrix_t) ();
+typedef void (* glReadPixels_t) (GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, GLvoid*);
+typedef void (* glRotatex_t) (GLfixed, GLfixed, GLfixed, GLfixed);
+typedef void (* glSampleCoverage_t) (GLclampf, GLboolean);
+typedef void (* glSampleCoveragex_t) (GLclampx, GLboolean);
+typedef void (* glScalex_t) (GLfixed, GLfixed, GLfixed);
+typedef void (* glScissor_t) (GLint, GLint, GLsizei, GLsizei);
+typedef void (* glShadeModel_t) (GLenum);
+typedef void (* glStencilFunc_t) (GLenum, GLint, GLuint);
+typedef void (* glStencilMask_t) (GLuint);
+typedef void (* glStencilOp_t) (GLenum, GLenum, GLenum);
+typedef void (* glTexCoordPointer_t) (GLint, GLenum, GLsizei, const GLvoid*);
+typedef void (* glTexEnvi_t) (GLenum, GLenum, GLint);
+typedef void (* glTexEnvx_t) (GLenum, GLenum, GLfixed);
+typedef void (* glTexEnviv_t) (GLenum, GLenum, const GLint*);
+typedef void (* glTexEnvxv_t) (GLenum, GLenum, const GLfixed*);
+typedef void (* glTexImage2D_t) (GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid*);
+typedef void (* glTexParameteri_t) (GLenum, GLenum, GLint);
+typedef void (* glTexParameterx_t) (GLenum, GLenum, GLfixed);
+typedef void (* glTexParameteriv_t) (GLenum, GLenum, const GLint*);
+typedef void (* glTexParameterxv_t) (GLenum, GLenum, const GLfixed*);
+typedef void (* glTexSubImage2D_t) (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid*);
+typedef void (* glTranslatex_t) (GLfixed, GLfixed, GLfixed);
+typedef void (* glVertexPointer_t) (GLint, GLenum, GLsizei, const GLvoid*);
+typedef void (* glViewport_t) (GLint, GLint, GLsizei, GLsizei);
+typedef void (* glPointSizePointerOES_t) (GLenum, GLsizei, const GLvoid*);
+typedef void (* glBlendEquationSeparateOES_t) (GLenum, GLenum);
+typedef void (* glBlendFuncSeparateOES_t) (GLenum, GLenum, GLenum, GLenum);
+typedef void (* glBlendEquationOES_t) (GLenum);
+typedef void (* glDrawTexsOES_t) (GLshort, GLshort, GLshort, GLshort, GLshort);
+typedef void (* glDrawTexiOES_t) (GLint, GLint, GLint, GLint, GLint);
+typedef void (* glDrawTexxOES_t) (GLfixed, GLfixed, GLfixed, GLfixed, GLfixed);
+typedef void (* glDrawTexsvOES_t) (const GLshort*);
+typedef void (* glDrawTexivOES_t) (const GLint*);
+typedef void (* glDrawTexxvOES_t) (const GLfixed*);
+typedef void (* glDrawTexfOES_t) (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+typedef void (* glDrawTexfvOES_t) (const GLfloat*);
+typedef void (* glEGLImageTargetTexture2DOES_t) (GLenum, GLeglImageOES);
+typedef void (* glEGLImageTargetRenderbufferStorageOES_t) (GLenum, GLeglImageOES);
+typedef void (* glAlphaFuncxOES_t) (GLenum, GLclampx);
+typedef void (* glClearColorxOES_t) (GLclampx, GLclampx, GLclampx, GLclampx);
+typedef void (* glClearDepthxOES_t) (GLclampx);
+typedef void (* glClipPlanexOES_t) (GLenum, const GLfixed*);
+typedef void (* glColor4xOES_t) (GLfixed, GLfixed, GLfixed, GLfixed);
+typedef void (* glDepthRangexOES_t) (GLclampx, GLclampx);
+typedef void (* glFogxOES_t) (GLenum, GLfixed);
+typedef void (* glFogxvOES_t) (GLenum, const GLfixed*);
+typedef void (* glFrustumxOES_t) (GLfixed, GLfixed, GLfixed, GLfixed, GLfixed, GLfixed);
+typedef void (* glGetClipPlanexOES_t) (GLenum, GLfixed*);
+typedef void (* glGetFixedvOES_t) (GLenum, GLfixed*);
+typedef void (* glGetLightxvOES_t) (GLenum, GLenum, GLfixed*);
+typedef void (* glGetMaterialxvOES_t) (GLenum, GLenum, GLfixed*);
+typedef void (* glGetTexEnvxvOES_t) (GLenum, GLenum, GLfixed*);
+typedef void (* glGetTexParameterxvOES_t) (GLenum, GLenum, GLfixed*);
+typedef void (* glLightModelxOES_t) (GLenum, GLfixed);
+typedef void (* glLightModelxvOES_t) (GLenum, const GLfixed*);
+typedef void (* glLightxOES_t) (GLenum, GLenum, GLfixed);
+typedef void (* glLightxvOES_t) (GLenum, GLenum, const GLfixed*);
+typedef void (* glLineWidthxOES_t) (GLfixed);
+typedef void (* glLoadMatrixxOES_t) (const GLfixed*);
+typedef void (* glMaterialxOES_t) (GLenum, GLenum, GLfixed);
+typedef void (* glMaterialxvOES_t) (GLenum, GLenum, const GLfixed*);
+typedef void (* glMultMatrixxOES_t) (const GLfixed*);
+typedef void (* glMultiTexCoord4xOES_t) (GLenum, GLfixed, GLfixed, GLfixed, GLfixed);
+typedef void (* glNormal3xOES_t) (GLfixed, GLfixed, GLfixed);
+typedef void (* glOrthoxOES_t) (GLfixed, GLfixed, GLfixed, GLfixed, GLfixed, GLfixed);
+typedef void (* glPointParameterxOES_t) (GLenum, GLfixed);
+typedef void (* glPointParameterxvOES_t) (GLenum, const GLfixed*);
+typedef void (* glPointSizexOES_t) (GLfixed);
+typedef void (* glPolygonOffsetxOES_t) (GLfixed, GLfixed);
+typedef void (* glRotatexOES_t) (GLfixed, GLfixed, GLfixed, GLfixed);
+typedef void (* glSampleCoveragexOES_t) (GLclampx, GLboolean);
+typedef void (* glScalexOES_t) (GLfixed, GLfixed, GLfixed);
+typedef void (* glTexEnvxOES_t) (GLenum, GLenum, GLfixed);
+typedef void (* glTexEnvxvOES_t) (GLenum, GLenum, const GLfixed*);
+typedef void (* glTexParameterxOES_t) (GLenum, GLenum, GLfixed);
+typedef void (* glTexParameterxvOES_t) (GLenum, GLenum, const GLfixed*);
+typedef void (* glTranslatexOES_t) (GLfixed, GLfixed, GLfixed);
+typedef GLboolean (* glIsRenderbufferOES_t) (GLuint);
+typedef void (* glBindRenderbufferOES_t) (GLenum, GLuint);
+typedef void (* glDeleteRenderbuffersOES_t) (GLsizei, const GLuint*);
+typedef void (* glGenRenderbuffersOES_t) (GLsizei, GLuint*);
+typedef void (* glRenderbufferStorageOES_t) (GLenum, GLenum, GLsizei, GLsizei);
+typedef void (* glGetRenderbufferParameterivOES_t) (GLenum, GLenum, GLint*);
+typedef GLboolean (* glIsFramebufferOES_t) (GLuint);
+typedef void (* glBindFramebufferOES_t) (GLenum, GLuint);
+typedef void (* glDeleteFramebuffersOES_t) (GLsizei, const GLuint*);
+typedef void (* glGenFramebuffersOES_t) (GLsizei, GLuint*);
+typedef GLenum (* glCheckFramebufferStatusOES_t) (GLenum);
+typedef void (* glFramebufferRenderbufferOES_t) (GLenum, GLenum, GLenum, GLuint);
+typedef void (* glFramebufferTexture2DOES_t) (GLenum, GLenum, GLenum, GLuint, GLint);
+typedef void (* glGetFramebufferAttachmentParameterivOES_t) (GLenum, GLenum, GLenum, GLint*);
+typedef void (* glGenerateMipmapOES_t) (GLenum);
+typedef void* (* glMapBufferOES_t) (GLenum, GLenum);
+typedef GLboolean (* glUnmapBufferOES_t) (GLenum);
+typedef void (* glGetBufferPointervOES_t) (GLenum, GLenum, GLvoid*);
+typedef void (* glCurrentPaletteMatrixOES_t) (GLuint);
+typedef void (* glLoadPaletteFromModelViewMatrixOES_t) ();
+typedef void (* glMatrixIndexPointerOES_t) (GLint, GLenum, GLsizei, const GLvoid*);
+typedef void (* glWeightPointerOES_t) (GLint, GLenum, GLsizei, const GLvoid*);
+typedef GLbitfield (* glQueryMatrixxOES_t) (GLfixed*, GLint*);
+typedef void (* glDepthRangefOES_t) (GLclampf, GLclampf);
+typedef void (* glFrustumfOES_t) (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+typedef void (* glOrthofOES_t) (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+typedef void (* glClipPlanefOES_t) (GLenum, const GLfloat*);
+typedef void (* glGetClipPlanefOES_t) (GLenum, GLfloat*);
+typedef void (* glClearDepthfOES_t) (GLclampf);
+typedef void (* glTexGenfOES_t) (GLenum, GLenum, GLfloat);
+typedef void (* glTexGenfvOES_t) (GLenum, GLenum, const GLfloat*);
+typedef void (* glTexGeniOES_t) (GLenum, GLenum, GLint);
+typedef void (* glTexGenivOES_t) (GLenum, GLenum, const GLint*);
+typedef void (* glTexGenxOES_t) (GLenum, GLenum, GLfixed);
+typedef void (* glTexGenxvOES_t) (GLenum, GLenum, const GLfixed*);
+typedef void (* glGetTexGenfvOES_t) (GLenum, GLenum, GLfloat*);
+typedef void (* glGetTexGenivOES_t) (GLenum, GLenum, GLint*);
+typedef void (* glGetTexGenxvOES_t) (GLenum, GLenum, GLfixed*);
+typedef void (* glBindVertexArrayOES_t) (GLuint);
+typedef void (* glDeleteVertexArraysOES_t) (GLsizei, const GLuint*);
+typedef void (* glGenVertexArraysOES_t) (GLsizei, GLuint*);
+typedef GLboolean (* glIsVertexArrayOES_t) (GLuint);
+typedef void (* glDiscardFramebufferEXT_t) (GLenum, GLsizei, const GLenum*);
+typedef void (* glMultiDrawArraysEXT_t) (GLenum, GLint*, GLsizei*, GLsizei);
+typedef void (* glMultiDrawElementsEXT_t) (GLenum, const GLsizei*, GLenum, const GLvoid**, GLsizei);
+typedef void (* glClipPlanefIMG_t) (GLenum, const GLfloat*);
+typedef void (* glClipPlanexIMG_t) (GLenum, const GLfixed*);
+typedef void (* glRenderbufferStorageMultisampleIMG_t) (GLenum, GLsizei, GLenum, GLsizei, GLsizei);
+typedef void (* glFramebufferTexture2DMultisampleIMG_t) (GLenum, GLenum, GLenum, GLuint, GLint, GLsizei);
+typedef void (* glDeleteFencesNV_t) (GLsizei, const GLuint*);
+typedef void (* glGenFencesNV_t) (GLsizei, GLuint*);
+typedef GLboolean (* glIsFenceNV_t) (GLuint);
+typedef GLboolean (* glTestFenceNV_t) (GLuint);
+typedef void (* glGetFenceivNV_t) (GLuint, GLenum, GLint*);
+typedef void (* glFinishFenceNV_t) (GLuint);
+typedef void (* glSetFenceNV_t) (GLuint, GLenum);
+typedef void (* glGetDriverControlsQCOM_t) (GLint*, GLsizei, GLuint*);
+typedef void (* glGetDriverControlStringQCOM_t) (GLuint, GLsizei, GLsizei*, GLchar*);
+typedef void (* glEnableDriverControlQCOM_t) (GLuint);
+typedef void (* glDisableDriverControlQCOM_t) (GLuint);
+typedef void (* glExtGetTexturesQCOM_t) (GLuint*, GLint, GLint*);
+typedef void (* glExtGetBuffersQCOM_t) (GLuint*, GLint, GLint*);
+typedef void (* glExtGetRenderbuffersQCOM_t) (GLuint*, GLint, GLint*);
+typedef void (* glExtGetFramebuffersQCOM_t) (GLuint*, GLint, GLint*);
+typedef void (* glExtGetTexLevelParameterivQCOM_t) (GLuint, GLenum, GLint, GLenum, GLint*);
+typedef void (* glExtTexObjectStateOverrideiQCOM_t) (GLenum, GLenum, GLint);
+typedef void (* glExtGetTexSubImageQCOM_t) (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, GLvoid*);
+typedef void (* glExtGetBufferPointervQCOM_t) (GLenum, GLvoid**);
+typedef void (* glExtGetShadersQCOM_t) (GLuint*, GLint, GLint*);
+typedef void (* glExtGetProgramsQCOM_t) (GLuint*, GLint, GLint*);
+typedef GLboolean (* glExtIsProgramBinaryQCOM_t) (GLuint);
+typedef void (* glExtGetProgramBinarySourceQCOM_t) (GLuint, GLenum, GLchar*, GLint*);
+typedef void (* glStartTilingQCOM_t) (GLuint, GLuint, GLuint, GLuint, GLbitfield);
+typedef void (* glEndTilingQCOM_t) (GLbitfield);
+
+
+#endif
diff --git a/opengl/tests/gles_android_wrapper/glesv1_emul_ifc.cpp b/opengl/tests/gles_android_wrapper/glesv1_emul_ifc.cpp
new file mode 100644
index 0000000..26c98a8
--- /dev/null
+++ b/opengl/tests/gles_android_wrapper/glesv1_emul_ifc.cpp
@@ -0,0 +1,39 @@
+/*
+* Copyright 2011 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.
+*/
+
+#include <stdlib.h>
+#include "ApiInitializer.h"
+#include <dlfcn.h>
+#include "gl_wrapper_context.h"
+
+extern "C" {
+    gl_wrapper_context_t *createFromLib(void *solib, gl_wrapper_context_t *(*accessor)());
+}
+
+gl_wrapper_context_t * createFromLib(void *solib, gl_wrapper_context_t *(accessor)())
+{
+    gl_wrapper_context_t *ctx = new gl_wrapper_context_t;
+    if (ctx == NULL) {
+        return NULL;
+    }
+    ApiInitializer *initializer = new ApiInitializer(solib);
+    ctx->initDispatchByName(ApiInitializer::s_getProc, initializer);
+    gl_wrapper_context_t::setContextAccessor(accessor);
+    delete initializer;
+    return ctx;
+}
+
+
diff --git a/opengl/tests/gles_android_wrapper/glesv2_emul_ifc.cpp b/opengl/tests/gles_android_wrapper/glesv2_emul_ifc.cpp
new file mode 100644
index 0000000..4ae13dd
--- /dev/null
+++ b/opengl/tests/gles_android_wrapper/glesv2_emul_ifc.cpp
@@ -0,0 +1,40 @@
+/*
+* Copyright 2011 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.
+*/
+
+#include <stdlib.h>
+#include "ApiInitializer.h"
+#include <dlfcn.h>
+#include "gl2_wrapper_context.h"
+
+extern "C" {
+    gl2_wrapper_context_t *createFromLib(void *solib, gl2_wrapper_context_t *(*accessor)());
+}
+
+gl2_wrapper_context_t * createFromLib(void *solib, gl2_wrapper_context_t *(*accessor)())
+{
+    gl2_wrapper_context_t *ctx = new gl2_wrapper_context_t;
+    if (ctx == NULL) {
+        return NULL;
+    }
+    ApiInitializer *initializer = new ApiInitializer(solib);
+    ctx->initDispatchByName(ApiInitializer::s_getProc, initializer);
+    gl2_wrapper_context_t::setContextAccessor(accessor);
+    delete initializer;
+    return ctx;
+}
+
+
+
diff --git a/opengl/tests/ut_rendercontrol_enc/Android.mk b/opengl/tests/ut_rendercontrol_enc/Android.mk
new file mode 100644
index 0000000..ae234b2
--- /dev/null
+++ b/opengl/tests/ut_rendercontrol_enc/Android.mk
@@ -0,0 +1,8 @@
+LOCAL_PATH := $(call my-dir)
+
+$(call emugl-begin-shared-library,libut_rendercontrol_enc)
+$(call emugl-import,libOpenglCodecCommon)
+$(call emugl-gen-encoder,$(LOCAL_PATH),ut_rendercontrol)
+$(call emugl-export,C_INCLUDES,$(LOCAL_PATH))
+$(call emugl-end-module)
+
diff --git a/opengl/tests/ut_rendercontrol_enc/ut_rendercontrol.attrib b/opengl/tests/ut_rendercontrol_enc/ut_rendercontrol.attrib
new file mode 100644
index 0000000..c47a9f9
--- /dev/null
+++ b/opengl/tests/ut_rendercontrol_enc/ut_rendercontrol.attrib
@@ -0,0 +1,4 @@
+GLOBAL
+	base_opcode 10000
+	encoder_headers <stdint.h>
+
diff --git a/opengl/tests/ut_rendercontrol_enc/ut_rendercontrol.in b/opengl/tests/ut_rendercontrol_enc/ut_rendercontrol.in
new file mode 100644
index 0000000..0d5942f
--- /dev/null
+++ b/opengl/tests/ut_rendercontrol_enc/ut_rendercontrol.in
@@ -0,0 +1,11 @@
+GL_ENTRY(int, createContext, uint32_t pid, uint32_t handle, uint32_t shareCtx, int version)
+GL_ENTRY(int, createSurface, uint32_t pid, uint32_t handle)
+GL_ENTRY(int, makeCurrentContext, uint32_t pid, uint32_t drawSurface, uint32_t readSurface, uint32_t ctxHandle)
+GL_ENTRY(void, swapBuffers, uint32_t pid, uint32_t surface)
+GL_ENTRY(int, destroyContext, uint32_t pid, uint32_t handle)
+GL_ENTRY(int, destroySurface, uint32_t pid, uint32_t handle)
+
+
+
+
+
diff --git a/opengl/tests/ut_rendercontrol_enc/ut_rendercontrol.types b/opengl/tests/ut_rendercontrol_enc/ut_rendercontrol.types
new file mode 100644
index 0000000..9d945ab
--- /dev/null
+++ b/opengl/tests/ut_rendercontrol_enc/ut_rendercontrol.types
@@ -0,0 +1,2 @@
+uint32_t 32 0x%08x false
+
diff --git a/opengl/tests/ut_rendercontrol_enc/ut_rendercontrol_types.h b/opengl/tests/ut_rendercontrol_enc/ut_rendercontrol_types.h
new file mode 100644
index 0000000..9b7864d
--- /dev/null
+++ b/opengl/tests/ut_rendercontrol_enc/ut_rendercontrol_types.h
@@ -0,0 +1,17 @@
+/*
+* Copyright (C) 2011 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.
+*/
+
+#include <stdint.h>
diff --git a/qemu-props/Android.mk b/qemu-props/Android.mk
new file mode 100644
index 0000000..885e5b7
--- /dev/null
+++ b/qemu-props/Android.mk
@@ -0,0 +1,28 @@
+# Copyright (C) 2009 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.
+
+# this file is used to build emulator-specific program tools
+# that should only run in the emulator.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+# The 'qemu-props' program is run from /system/etc/init.goldfish.rc
+# to setup various system properties sent by the emulator program.
+#
+include $(CLEAR_VARS)
+LOCAL_MODULE    := qemu-props
+LOCAL_SRC_FILES := qemu-props.c
+LOCAL_SHARED_LIBRARIES := libcutils
+include $(BUILD_EXECUTABLE)
diff --git a/qemu-props/qemu-props.c b/qemu-props/qemu-props.c
new file mode 100644
index 0000000..56d510f
--- /dev/null
+++ b/qemu-props/qemu-props.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2009 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.
+ */
+
+/* this program is used to read a set of system properties and their values
+ * from the emulator program and set them in the currently-running emulated
+ * system. It does so by connecting to the 'boot-properties' qemud service.
+ *
+ * This program should be run as root and called from
+ * /system/etc/init.goldfish.rc exclusively.
+ */
+
+#define LOG_TAG  "qemu-props"
+
+#define DEBUG  1
+
+#if DEBUG
+#  include <cutils/log.h>
+#  define  DD(...)    ALOGI(__VA_ARGS__)
+#else
+#  define  DD(...)    ((void)0)
+#endif
+
+#include <cutils/properties.h>
+#include <unistd.h>
+#include <hardware/qemud.h>
+
+/* Name of the qemud service we want to connect to.
+ */
+#define  QEMUD_SERVICE  "boot-properties"
+
+#define  MAX_TRIES      5
+
+int  main(void)
+{
+    int  qemud_fd, count = 0;
+
+    /* try to connect to the qemud service */
+    {
+        int  tries = MAX_TRIES;
+
+        while (1) {
+            qemud_fd = qemud_channel_open( "boot-properties" );
+            if (qemud_fd >= 0)
+                break;
+
+            if (--tries <= 0) {
+                DD("Could not connect after too many tries. Aborting");
+                return 1;
+            }
+
+            DD("waiting 1s to wait for qemud.");
+            sleep(1);
+        }
+    }
+
+    DD("connected to '%s' qemud service.", QEMUD_SERVICE);
+
+    /* send the 'list' command to the service */
+    if (qemud_channel_send(qemud_fd, "list", -1) < 0) {
+        DD("could not send command to '%s' service", QEMUD_SERVICE);
+        return 1;
+    }
+
+    /* read each system property as a single line from the service,
+     * until exhaustion.
+     */
+    for (;;)
+    {
+#define  BUFF_SIZE   (PROPERTY_KEY_MAX + PROPERTY_VALUE_MAX + 2)
+        DD("receiving..");
+        char* q;
+        char  temp[BUFF_SIZE];
+        int   len = qemud_channel_recv(qemud_fd, temp, sizeof temp - 1);
+
+        /* lone NUL-byte signals end of properties */
+        if (len < 0 || len > BUFF_SIZE-1 || temp[0] == '\0')
+            break;
+
+        temp[len] = '\0';  /* zero-terminate string */
+
+        DD("received: %.*s", len, temp);
+
+        /* separate propery name from value */
+        q = strchr(temp, '=');
+        if (q == NULL) {
+            DD("invalid format, ignored.");
+            continue;
+        }
+        *q++ = '\0';
+
+        if (property_set(temp, q) < 0) {
+            DD("could not set property '%s' to '%s'", temp, q);
+        } else {
+            count += 1;
+        }
+    }
+
+
+    /* finally, close the channel and exit */
+    close(qemud_fd);
+    DD("exiting (%d properties set).", count);
+    return 0;
+}
diff --git a/qemud/Android.mk b/qemud/Android.mk
new file mode 100644
index 0000000..237572c
--- /dev/null
+++ b/qemud/Android.mk
@@ -0,0 +1,20 @@
+# Copyright 2008 The Android Open Source Project
+
+# We're moving the emulator-specific platform libs to
+# development.git/tools/emulator/. The following test is to ensure
+# smooth builds even if the tree contains both versions.
+#
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	qemud.c
+
+
+LOCAL_SHARED_LIBRARIES := \
+	libcutils \
+
+LOCAL_MODULE:= qemud
+
+include $(BUILD_EXECUTABLE)
diff --git a/qemud/qemud.c b/qemud/qemud.c
new file mode 100644
index 0000000..e836376
--- /dev/null
+++ b/qemud/qemud.c
@@ -0,0 +1,1719 @@
+#include <stdint.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <termios.h>
+#include <cutils/sockets.h>
+
+/*
+ *  the qemud daemon program is only used within Android as a bridge
+ *  between the emulator program and the emulated system. it really works as
+ *  a simple stream multiplexer that works as follows:
+ *
+ *    - qemud is started by init following instructions in
+ *      /system/etc/init.goldfish.rc (i.e. it is never started on real devices)
+ *
+ *    - qemud communicates with the emulator program through a single serial
+ *      port, whose name is passed through a kernel boot parameter
+ *      (e.g. android.qemud=ttyS1)
+ *
+ *    - qemud binds one unix local stream socket (/dev/socket/qemud, created
+ *      by init through /system/etc/init.goldfish.rc).
+ *
+ *
+ *      emulator <==serial==> qemud <---> /dev/socket/qemud <-+--> client1
+ *                                                            |
+ *                                                            +--> client2
+ *
+ *   - the special channel index 0 is used by the emulator and qemud only.
+ *     other channel numbers correspond to clients. More specifically,
+ *     connection are created like this:
+ *
+ *     * the client connects to /dev/socket/qemud
+ *
+ *     * the client sends the service name through the socket, as
+ *            <service-name>
+ *
+ *     * qemud creates a "Client" object internally, assigns it an
+ *       internal unique channel number > 0, then sends a connection
+ *       initiation request to the emulator (i.e. through channel 0):
+ *
+ *           connect:<id>:<name>
+ *
+ *       where <name> is the service name, and <id> is a 2-hexchar
+ *       number corresponding to the channel number.
+ *
+ *     * in case of success, the emulator responds through channel 0
+ *       with:
+ *
+ *           ok:connect:<id>
+ *
+ *       after this, all messages between the client and the emulator
+ *       are passed in pass-through mode.
+ *
+ *     * if the emulator refuses the service connection, it will
+ *       send the following through channel 0:
+ *
+ *           ko:connect:<id>:reason-for-failure
+ *
+ *     * If the client closes the connection, qemud sends the following
+ *       to the emulator:
+ *
+ *           disconnect:<id>
+ *
+ *       The same message is the opposite direction if the emulator
+ *       chooses to close the connection.
+ *
+ *     * any command sent through channel 0 to the emulator that is
+ *       not properly recognized will be answered by:
+ *
+ *           ko:unknown command
+ *
+ *
+ *  Internally, the daemon maintains a "Client" object for each client
+ *  connection (i.e. accepting socket connection).
+ */
+
+/* name of the single control socket used by the daemon */
+#define CONTROL_SOCKET_NAME  "qemud"
+
+#define  DEBUG     0
+#define  T_ACTIVE  0  /* set to 1 to dump traffic */
+
+#if DEBUG
+#  define LOG_TAG  "qemud"
+#  include <cutils/log.h>
+#  define  D(...)   ALOGD(__VA_ARGS__)
+#else
+#  define  D(...)  ((void)0)
+#  define  T(...)  ((void)0)
+#endif
+
+#if T_ACTIVE
+#  define  T(...)   D(__VA_ARGS__)
+#else
+#  define  T(...)   ((void)0)
+#endif
+
+/** UTILITIES
+ **/
+
+static void
+fatal( const char*  fmt, ... )
+{
+    va_list  args;
+    va_start(args, fmt);
+    fprintf(stderr, "PANIC: ");
+    vfprintf(stderr, fmt, args);
+    fprintf(stderr, "\n" );
+    va_end(args);
+    exit(1);
+}
+
+static void*
+xalloc( size_t   sz )
+{
+    void*  p;
+
+    if (sz == 0)
+        return NULL;
+
+    p = malloc(sz);
+    if (p == NULL)
+        fatal( "not enough memory" );
+
+    return p;
+}
+
+#define  xnew(p)   (p) = xalloc(sizeof(*(p)))
+
+static void*
+xalloc0( size_t  sz )
+{
+    void*  p = xalloc(sz);
+    memset( p, 0, sz );
+    return p;
+}
+
+#define  xnew0(p)   (p) = xalloc0(sizeof(*(p)))
+
+#define  xfree(p)    (free((p)), (p) = NULL)
+
+static void*
+xrealloc( void*  block, size_t  size )
+{
+    void*  p = realloc( block, size );
+
+    if (p == NULL && size > 0)
+        fatal( "not enough memory" );
+
+    return p;
+}
+
+#define  xrenew(p,count)  (p) = xrealloc((p),sizeof(*(p))*(count))
+
+static int
+hex2int( const uint8_t*  data, int  len )
+{
+    int  result = 0;
+    while (len > 0) {
+        int       c = *data++;
+        unsigned  d;
+
+        result <<= 4;
+        do {
+            d = (unsigned)(c - '0');
+            if (d < 10)
+                break;
+
+            d = (unsigned)(c - 'a');
+            if (d < 6) {
+                d += 10;
+                break;
+            }
+
+            d = (unsigned)(c - 'A');
+            if (d < 6) {
+                d += 10;
+                break;
+            }
+
+            return -1;
+        }
+        while (0);
+
+        result |= d;
+        len    -= 1;
+    }
+    return  result;
+}
+
+
+static void
+int2hex( int  value, uint8_t*  to, int  width )
+{
+    int  nn = 0;
+    static const char hexchars[16] = "0123456789abcdef";
+
+    for ( --width; width >= 0; width--, nn++ ) {
+        to[nn] = hexchars[(value >> (width*4)) & 15];
+    }
+}
+
+static int
+fd_read(int  fd, void*  to, int  len)
+{
+    int  ret;
+
+    do {
+        ret = read(fd, to, len);
+    } while (ret < 0 && errno == EINTR);
+
+    return ret;
+}
+
+static int
+fd_write(int  fd, const void*  from, int  len)
+{
+    int  ret;
+
+    do {
+        ret = write(fd, from, len);
+    } while (ret < 0 && errno == EINTR);
+
+    return ret;
+}
+
+static void
+fd_setnonblock(int  fd)
+{
+    int  ret, flags;
+
+    do {
+        flags = fcntl(fd, F_GETFD);
+    } while (flags < 0 && errno == EINTR);
+
+    if (flags < 0) {
+        fatal( "%s: could not get flags for fd %d: %s",
+               __FUNCTION__, fd, strerror(errno) );
+    }
+
+    do {
+        ret = fcntl(fd, F_SETFD, flags | O_NONBLOCK);
+    } while (ret < 0 && errno == EINTR);
+
+    if (ret < 0) {
+        fatal( "%s: could not set fd %d to non-blocking: %s",
+               __FUNCTION__, fd, strerror(errno) );
+    }
+}
+
+
+static int
+fd_accept(int  fd)
+{
+    struct sockaddr  from;
+    socklen_t        fromlen = sizeof(from);
+    int              ret;
+
+    do {
+        ret = accept(fd, &from, &fromlen);
+    } while (ret < 0 && errno == EINTR);
+
+    return ret;
+}
+
+/** FD EVENT LOOP
+ **/
+
+/* A Looper object is used to monitor activity on one or more
+ * file descriptors (e.g sockets).
+ *
+ * - call looper_add() to register a function that will be
+ *   called when events happen on the file descriptor.
+ *
+ * - call looper_enable() or looper_disable() to enable/disable
+ *   the set of monitored events for a given file descriptor.
+ *
+ * - call looper_del() to unregister a file descriptor.
+ *   this does *not* close the file descriptor.
+ *
+ * Note that you can only provide a single function to handle
+ * all events related to a given file descriptor.
+
+ * You can call looper_enable/_disable/_del within a function
+ * callback.
+ */
+
+/* the current implementation uses Linux's epoll facility
+ * the event mask we use are simply combinations of EPOLLIN
+ * EPOLLOUT, EPOLLHUP and EPOLLERR
+ */
+#include <sys/epoll.h>
+
+#define  MAX_CHANNELS  16
+#define  MAX_EVENTS    (MAX_CHANNELS+1)  /* each channel + the serial fd */
+
+/* the event handler function type, 'user' is a user-specific
+ * opaque pointer passed to looper_add().
+ */
+typedef void (*EventFunc)( void*  user, int  events );
+
+/* bit flags for the LoopHook structure.
+ *
+ * HOOK_PENDING means that an event happened on the
+ * corresponding file descriptor.
+ *
+ * HOOK_CLOSING is used to delay-close monitored
+ * file descriptors.
+ */
+enum {
+    HOOK_PENDING = (1 << 0),
+    HOOK_CLOSING = (1 << 1),
+};
+
+/* A LoopHook structure is used to monitor a given
+ * file descriptor and record its event handler.
+ */
+typedef struct {
+    int        fd;
+    int        wanted;  /* events we are monitoring */
+    int        events;  /* events that occured */
+    int        state;   /* see HOOK_XXX constants */
+    void*      ev_user; /* user-provided handler parameter */
+    EventFunc  ev_func; /* event handler callback */
+} LoopHook;
+
+/* Looper is the main object modeling a looper object
+ */
+typedef struct {
+    int                  epoll_fd;
+    int                  num_fds;
+    int                  max_fds;
+    struct epoll_event*  events;
+    LoopHook*            hooks;
+} Looper;
+
+/* initialize a looper object */
+static void
+looper_init( Looper*  l )
+{
+    l->epoll_fd = epoll_create(4);
+    l->num_fds  = 0;
+    l->max_fds  = 0;
+    l->events   = NULL;
+    l->hooks    = NULL;
+}
+
+/* finalize a looper object */
+static void
+looper_done( Looper*  l )
+{
+    xfree(l->events);
+    xfree(l->hooks);
+    l->max_fds = 0;
+    l->num_fds = 0;
+
+    close(l->epoll_fd);
+    l->epoll_fd  = -1;
+}
+
+/* return the LoopHook corresponding to a given
+ * monitored file descriptor, or NULL if not found
+ */
+static LoopHook*
+looper_find( Looper*  l, int  fd )
+{
+    LoopHook*  hook = l->hooks;
+    LoopHook*  end  = hook + l->num_fds;
+
+    for ( ; hook < end; hook++ ) {
+        if (hook->fd == fd)
+            return hook;
+    }
+    return NULL;
+}
+
+/* grow the arrays in the looper object */
+static void
+looper_grow( Looper*  l )
+{
+    int  old_max = l->max_fds;
+    int  new_max = old_max + (old_max >> 1) + 4;
+    int  n;
+
+    xrenew( l->events, new_max );
+    xrenew( l->hooks,  new_max );
+    l->max_fds = new_max;
+
+    /* now change the handles to all events */
+    for (n = 0; n < l->num_fds; n++) {
+        struct epoll_event ev;
+        LoopHook*          hook = l->hooks + n;
+
+        ev.events   = hook->wanted;
+        ev.data.ptr = hook;
+        epoll_ctl( l->epoll_fd, EPOLL_CTL_MOD, hook->fd, &ev );
+    }
+}
+
+/* register a file descriptor and its event handler.
+ * no event mask will be enabled
+ */
+static void
+looper_add( Looper*  l, int  fd, EventFunc  func, void*  user )
+{
+    struct epoll_event  ev;
+    LoopHook*           hook;
+
+    if (l->num_fds >= l->max_fds)
+        looper_grow(l);
+
+    hook = l->hooks + l->num_fds;
+
+    hook->fd      = fd;
+    hook->ev_user = user;
+    hook->ev_func = func;
+    hook->state   = 0;
+    hook->wanted  = 0;
+    hook->events  = 0;
+
+    fd_setnonblock(fd);
+
+    ev.events   = 0;
+    ev.data.ptr = hook;
+    epoll_ctl( l->epoll_fd, EPOLL_CTL_ADD, fd, &ev );
+
+    l->num_fds += 1;
+}
+
+/* unregister a file descriptor and its event handler
+ */
+static void
+looper_del( Looper*  l, int  fd )
+{
+    LoopHook*  hook = looper_find( l, fd );
+
+    if (!hook) {
+        D( "%s: invalid fd: %d", __FUNCTION__, fd );
+        return;
+    }
+    /* don't remove the hook yet */
+    hook->state |= HOOK_CLOSING;
+
+    epoll_ctl( l->epoll_fd, EPOLL_CTL_DEL, fd, NULL );
+}
+
+/* enable monitoring of certain events for a file
+ * descriptor. This adds 'events' to the current
+ * event mask
+ */
+static void
+looper_enable( Looper*  l, int  fd, int  events )
+{
+    LoopHook*  hook = looper_find( l, fd );
+
+    if (!hook) {
+        D("%s: invalid fd: %d", __FUNCTION__, fd );
+        return;
+    }
+
+    if (events & ~hook->wanted) {
+        struct epoll_event  ev;
+
+        hook->wanted |= events;
+        ev.events   = hook->wanted;
+        ev.data.ptr = hook;
+
+        epoll_ctl( l->epoll_fd, EPOLL_CTL_MOD, fd, &ev );
+    }
+}
+
+/* disable monitoring of certain events for a file
+ * descriptor. This ignores events that are not
+ * currently enabled.
+ */
+static void
+looper_disable( Looper*  l, int  fd, int  events )
+{
+    LoopHook*  hook = looper_find( l, fd );
+
+    if (!hook) {
+        D("%s: invalid fd: %d", __FUNCTION__, fd );
+        return;
+    }
+
+    if (events & hook->wanted) {
+        struct epoll_event  ev;
+
+        hook->wanted &= ~events;
+        ev.events   = hook->wanted;
+        ev.data.ptr = hook;
+
+        epoll_ctl( l->epoll_fd, EPOLL_CTL_MOD, fd, &ev );
+    }
+}
+
+/* wait until an event occurs on one of the registered file
+ * descriptors. Only returns in case of error !!
+ */
+static void
+looper_loop( Looper*  l )
+{
+    for (;;) {
+        int  n, count;
+
+        do {
+            count = epoll_wait( l->epoll_fd, l->events, l->num_fds, -1 );
+        } while (count < 0 && errno == EINTR);
+
+        if (count < 0) {
+            D("%s: error: %s", __FUNCTION__, strerror(errno) );
+            return;
+        }
+
+        if (count == 0) {
+            D("%s: huh ? epoll returned count=0", __FUNCTION__);
+            continue;
+        }
+
+        /* mark all pending hooks */
+        for (n = 0; n < count; n++) {
+            LoopHook*  hook = l->events[n].data.ptr;
+            hook->state  = HOOK_PENDING;
+            hook->events = l->events[n].events;
+        }
+
+        /* execute hook callbacks. this may change the 'hooks'
+         * and 'events' array, as well as l->num_fds, so be careful */
+        for (n = 0; n < l->num_fds; n++) {
+            LoopHook*  hook = l->hooks + n;
+            if (hook->state & HOOK_PENDING) {
+                hook->state &= ~HOOK_PENDING;
+                hook->ev_func( hook->ev_user, hook->events );
+            }
+        }
+
+        /* now remove all the hooks that were closed by
+         * the callbacks */
+        for (n = 0; n < l->num_fds;) {
+            struct epoll_event ev;
+            LoopHook*  hook = l->hooks + n;
+
+            if (!(hook->state & HOOK_CLOSING)) {
+                n++;
+                continue;
+            }
+
+            hook[0]     = l->hooks[l->num_fds-1];
+            l->num_fds -= 1;
+            ev.events   = hook->wanted;
+            ev.data.ptr = hook;
+            epoll_ctl( l->epoll_fd, EPOLL_CTL_MOD, hook->fd, &ev );
+        }
+    }
+}
+
+#if T_ACTIVE
+char*
+quote( const void*  data, int  len )
+{
+    const char*  p   = data;
+    const char*  end = p + len;
+    int          count = 0;
+    int          phase = 0;
+    static char*  buff = NULL;
+
+    for (phase = 0; phase < 2; phase++) {
+        if (phase != 0) {
+            xfree(buff);
+            buff = xalloc(count+1);
+        }
+        count = 0;
+        for (p = data; p < end; p++) {
+            int  c = *p;
+
+            if (c == '\\') {
+                if (phase != 0) {
+                    buff[count] = buff[count+1] = '\\';
+                }
+                count += 2;
+                continue;
+            }
+
+            if (c >= 32 && c < 127) {
+                if (phase != 0)
+                    buff[count] = c;
+                count += 1;
+                continue;
+            }
+
+
+            if (c == '\t') {
+                if (phase != 0) {
+                    memcpy(buff+count, "<TAB>", 5);
+                }
+                count += 5;
+                continue;
+            }
+            if (c == '\n') {
+                if (phase != 0) {
+                    memcpy(buff+count, "<LN>", 4);
+                }
+                count += 4;
+                continue;
+            }
+            if (c == '\r') {
+                if (phase != 0) {
+                    memcpy(buff+count, "<CR>", 4);
+                }
+                count += 4;
+                continue;
+            }
+
+            if (phase != 0) {
+                buff[count+0] = '\\';
+                buff[count+1] = 'x';
+                buff[count+2] = "0123456789abcdef"[(c >> 4) & 15];
+                buff[count+3] = "0123456789abcdef"[     (c) & 15];
+            }
+            count += 4;
+        }
+    }
+    buff[count] = 0;
+    return buff;
+}
+#endif /* T_ACTIVE */
+
+/** PACKETS
+ **
+ ** We need a way to buffer data before it can be sent to the
+ ** corresponding file descriptor. We use linked list of Packet
+ ** objects to do this.
+ **/
+
+typedef struct Packet   Packet;
+
+#define  MAX_PAYLOAD  4000
+
+struct Packet {
+    Packet*   next;
+    int       len;
+    int       channel;
+    uint8_t   data[ MAX_PAYLOAD ];
+};
+
+/* we expect to alloc/free a lot of packets during
+ * operations so use a single linked list of free packets
+ * to keep things speedy and simple.
+ */
+static Packet*   _free_packets;
+
+/* Allocate a packet */
+static Packet*
+packet_alloc(void)
+{
+    Packet*  p = _free_packets;
+    if (p != NULL) {
+        _free_packets = p->next;
+    } else {
+        xnew(p);
+    }
+    p->next    = NULL;
+    p->len     = 0;
+    p->channel = -1;
+    return p;
+}
+
+/* Release a packet. This takes the address of a packet
+ * pointer that will be set to NULL on exit (avoids
+ * referencing dangling pointers in case of bugs)
+ */
+static void
+packet_free( Packet*  *ppacket )
+{
+    Packet*  p = *ppacket;
+    if (p) {
+        p->next       = _free_packets;
+        _free_packets = p;
+        *ppacket = NULL;
+    }
+}
+
+/** PACKET RECEIVER
+ **
+ ** Simple abstraction for something that can receive a packet
+ ** from a FDHandler (see below) or something else.
+ **
+ ** Send a packet to it with 'receiver_post'
+ **
+ ** Call 'receiver_close' to indicate that the corresponding
+ ** packet source was closed.
+ **/
+
+typedef void (*PostFunc) ( void*  user, Packet*  p );
+typedef void (*CloseFunc)( void*  user );
+
+typedef struct {
+    PostFunc   post;
+    CloseFunc  close;
+    void*      user;
+} Receiver;
+
+/* post a packet to a receiver. Note that this transfers
+ * ownership of the packet to the receiver.
+ */
+static __inline__ void
+receiver_post( Receiver*  r, Packet*  p )
+{
+    if (r->post)
+        r->post( r->user, p );
+    else
+        packet_free(&p);
+}
+
+/* tell a receiver the packet source was closed.
+ * this will also prevent further posting to the
+ * receiver.
+ */
+static __inline__ void
+receiver_close( Receiver*  r )
+{
+    if (r->close) {
+        r->close( r->user );
+        r->close = NULL;
+    }
+    r->post  = NULL;
+}
+
+
+/** FD HANDLERS
+ **
+ ** these are smart listeners that send incoming packets to a receiver
+ ** and can queue one or more outgoing packets and send them when
+ ** possible to the FD.
+ **
+ ** note that we support clean shutdown of file descriptors,
+ ** i.e. we try to send all outgoing packets before destroying
+ ** the FDHandler.
+ **/
+
+typedef struct FDHandler      FDHandler;
+typedef struct FDHandlerList  FDHandlerList;
+
+struct FDHandler {
+    int             fd;
+    FDHandlerList*  list;
+    char            closing;
+    Receiver        receiver[1];
+
+    /* queue of outgoing packets */
+    int             out_pos;
+    Packet*         out_first;
+    Packet**        out_ptail;
+
+    FDHandler*      next;
+    FDHandler**     pref;
+
+};
+
+struct FDHandlerList {
+    /* the looper that manages the fds */
+    Looper*      looper;
+
+    /* list of active FDHandler objects */
+    FDHandler*   active;
+
+    /* list of closing FDHandler objects.
+     * these are waiting to push their
+     * queued packets to the fd before
+     * freeing themselves.
+     */
+    FDHandler*   closing;
+
+};
+
+/* remove a FDHandler from its current list */
+static void
+fdhandler_remove( FDHandler*  f )
+{
+    f->pref[0] = f->next;
+    if (f->next)
+        f->next->pref = f->pref;
+}
+
+/* add a FDHandler to a given list */
+static void
+fdhandler_prepend( FDHandler*  f, FDHandler**  list )
+{
+    f->next = list[0];
+    f->pref = list;
+    list[0] = f;
+    if (f->next)
+        f->next->pref = &f->next;
+}
+
+/* initialize a FDHandler list */
+static void
+fdhandler_list_init( FDHandlerList*  list, Looper*  looper )
+{
+    list->looper  = looper;
+    list->active  = NULL;
+    list->closing = NULL;
+}
+
+
+/* close a FDHandler (and free it). Note that this will not
+ * perform a graceful shutdown, i.e. all packets in the
+ * outgoing queue will be immediately free.
+ *
+ * this *will* notify the receiver that the file descriptor
+ * was closed.
+ *
+ * you should call fdhandler_shutdown() if you want to
+ * notify the FDHandler that its packet source is closed.
+ */
+static void
+fdhandler_close( FDHandler*  f )
+{
+    /* notify receiver */
+    receiver_close(f->receiver);
+
+    /* remove the handler from its list */
+    fdhandler_remove(f);
+
+    /* get rid of outgoing packet queue */
+    if (f->out_first != NULL) {
+        Packet*  p;
+        while ((p = f->out_first) != NULL) {
+            f->out_first = p->next;
+            packet_free(&p);
+        }
+    }
+
+    /* get rid of file descriptor */
+    if (f->fd >= 0) {
+        looper_del( f->list->looper, f->fd );
+        close(f->fd);
+        f->fd = -1;
+    }
+
+    f->list = NULL;
+    xfree(f);
+}
+
+/* Ask the FDHandler to cleanly shutdown the connection,
+ * i.e. send any pending outgoing packets then auto-free
+ * itself.
+ */
+static void
+fdhandler_shutdown( FDHandler*  f )
+{
+    /* prevent later fdhandler_close() to
+     * call the receiver's close.
+     */
+    f->receiver->close = NULL;
+
+    if (f->out_first != NULL && !f->closing)
+    {
+        /* move the handler to the 'closing' list */
+        f->closing = 1;
+        fdhandler_remove(f);
+        fdhandler_prepend(f, &f->list->closing);
+        return;
+    }
+
+    fdhandler_close(f);
+}
+
+/* Enqueue a new packet that the FDHandler will
+ * send through its file descriptor.
+ */
+static void
+fdhandler_enqueue( FDHandler*  f, Packet*  p )
+{
+    Packet*  first = f->out_first;
+
+    p->next         = NULL;
+    f->out_ptail[0] = p;
+    f->out_ptail    = &p->next;
+
+    if (first == NULL) {
+        f->out_pos = 0;
+        looper_enable( f->list->looper, f->fd, EPOLLOUT );
+    }
+}
+
+
+/* FDHandler file descriptor event callback for read/write ops */
+static void
+fdhandler_event( FDHandler*  f, int  events )
+{
+   int  len;
+
+    /* in certain cases, it's possible to have both EPOLLIN and
+     * EPOLLHUP at the same time. This indicates that there is incoming
+     * data to read, but that the connection was nonetheless closed
+     * by the sender. Be sure to read the data before closing
+     * the receiver to avoid packet loss.
+     */
+
+    if (events & EPOLLIN) {
+        Packet*  p = packet_alloc();
+        int      len;
+
+        if ((len = fd_read(f->fd, p->data, MAX_PAYLOAD)) < 0) {
+            D("%s: can't recv: %s", __FUNCTION__, strerror(errno));
+            packet_free(&p);
+        } else if (len > 0) {
+            p->len     = len;
+            p->channel = -101;  /* special debug value, not used */
+            receiver_post( f->receiver, p );
+        }
+    }
+
+    if (events & (EPOLLHUP|EPOLLERR)) {
+        /* disconnection */
+        D("%s: disconnect on fd %d", __FUNCTION__, f->fd);
+        fdhandler_close(f);
+        return;
+    }
+
+    if (events & EPOLLOUT && f->out_first) {
+        Packet*  p = f->out_first;
+        int      avail, len;
+
+        avail = p->len - f->out_pos;
+        if ((len = fd_write(f->fd, p->data + f->out_pos, avail)) < 0) {
+            D("%s: can't send: %s", __FUNCTION__, strerror(errno));
+        } else {
+            f->out_pos += len;
+            if (f->out_pos >= p->len) {
+                f->out_pos   = 0;
+                f->out_first = p->next;
+                packet_free(&p);
+                if (f->out_first == NULL) {
+                    f->out_ptail = &f->out_first;
+                    looper_disable( f->list->looper, f->fd, EPOLLOUT );
+                }
+            }
+        }
+    }
+}
+
+
+/* Create a new FDHandler that monitors read/writes */
+static FDHandler*
+fdhandler_new( int             fd,
+               FDHandlerList*  list,
+               Receiver*       receiver )
+{
+    FDHandler*  f = xalloc0(sizeof(*f));
+
+    f->fd          = fd;
+    f->list        = list;
+    f->receiver[0] = receiver[0];
+    f->out_first   = NULL;
+    f->out_ptail   = &f->out_first;
+    f->out_pos     = 0;
+
+    fdhandler_prepend(f, &list->active);
+
+    looper_add( list->looper, fd, (EventFunc) fdhandler_event, f );
+    looper_enable( list->looper, fd, EPOLLIN );
+
+    return f;
+}
+
+
+/* event callback function to monitor accepts() on server sockets.
+ * the convention used here is that the receiver will receive a
+ * dummy packet with the new client socket in p->channel
+ */
+static void
+fdhandler_accept_event( FDHandler*  f, int  events )
+{
+    if (events & EPOLLIN) {
+        /* this is an accept - send a dummy packet to the receiver */
+        Packet*  p = packet_alloc();
+
+        D("%s: accepting on fd %d", __FUNCTION__, f->fd);
+        p->data[0] = 1;
+        p->len     = 1;
+        p->channel = fd_accept(f->fd);
+        if (p->channel < 0) {
+            D("%s: accept failed ?: %s", __FUNCTION__, strerror(errno));
+            packet_free(&p);
+            return;
+        }
+        receiver_post( f->receiver, p );
+    }
+
+    if (events & (EPOLLHUP|EPOLLERR)) {
+        /* disconnecting !! */
+        D("%s: closing accept fd %d", __FUNCTION__, f->fd);
+        fdhandler_close(f);
+        return;
+    }
+}
+
+
+/* Create a new FDHandler used to monitor new connections on a
+ * server socket. The receiver must expect the new connection
+ * fd in the 'channel' field of a dummy packet.
+ */
+static FDHandler*
+fdhandler_new_accept( int             fd,
+                      FDHandlerList*  list,
+                      Receiver*       receiver )
+{
+    FDHandler*  f = xalloc0(sizeof(*f));
+
+    f->fd          = fd;
+    f->list        = list;
+    f->receiver[0] = receiver[0];
+
+    fdhandler_prepend(f, &list->active);
+
+    looper_add( list->looper, fd, (EventFunc) fdhandler_accept_event, f );
+    looper_enable( list->looper, fd, EPOLLIN );
+    listen( fd, 5 );
+
+    return f;
+}
+
+/** SERIAL CONNECTION STATE
+ **
+ ** The following is used to handle the framing protocol
+ ** used on the serial port connection.
+ **/
+
+/* each packet is made of a 6 byte header followed by a payload
+ * the header looks like:
+ *
+ *   offset   size    description
+ *       0       2    a 2-byte hex string for the channel number
+ *       4       4    a 4-char hex string for the size of the payload
+ *       6       n    the payload itself
+ */
+#define  HEADER_SIZE    6
+#define  CHANNEL_OFFSET 0
+#define  LENGTH_OFFSET  2
+#define  CHANNEL_SIZE   2
+#define  LENGTH_SIZE    4
+
+#define  CHANNEL_CONTROL  0
+
+/* The Serial object receives data from the serial port,
+ * extracts the payload size and channel index, then sends
+ * the resulting messages as a packet to a generic receiver.
+ *
+ * You can also use serial_send to send a packet through
+ * the serial port.
+ */
+typedef struct Serial {
+    FDHandler*  fdhandler;   /* used to monitor serial port fd */
+    Receiver    receiver[1]; /* send payload there */
+    int         in_len;      /* current bytes in input packet */
+    int         in_datalen;  /* payload size, or 0 when reading header */
+    int         in_channel;  /* extracted channel number */
+    Packet*     in_packet;   /* used to read incoming packets */
+} Serial;
+
+
+/* a callback called when the serial port's fd is closed */
+static void
+serial_fd_close( Serial*  s )
+{
+    fatal("unexpected serial port close !!");
+}
+
+static void
+serial_dump( Packet*  p, const char*  funcname )
+{
+    T("%s: %03d bytes: '%s'",
+      funcname, p->len, quote(p->data, p->len));
+}
+
+/* a callback called when a packet arrives from the serial port's FDHandler.
+ *
+ * This will essentially parse the header, extract the channel number and
+ * the payload size and store them in 'in_datalen' and 'in_channel'.
+ *
+ * After that, the payload is sent to the receiver once completed.
+ */
+static void
+serial_fd_receive( Serial*  s, Packet*  p )
+{
+    int      rpos  = 0, rcount = p->len;
+    Packet*  inp   = s->in_packet;
+    int      inpos = s->in_len;
+
+    serial_dump( p, __FUNCTION__ );
+
+    while (rpos < rcount)
+    {
+        int  avail = rcount - rpos;
+
+        /* first, try to read the header */
+        if (s->in_datalen == 0) {
+            int  wanted = HEADER_SIZE - inpos;
+            if (avail > wanted)
+                avail = wanted;
+
+            memcpy( inp->data + inpos, p->data + rpos, avail );
+            inpos += avail;
+            rpos  += avail;
+
+            if (inpos == HEADER_SIZE) {
+                s->in_datalen = hex2int( inp->data + LENGTH_OFFSET,  LENGTH_SIZE );
+                s->in_channel = hex2int( inp->data + CHANNEL_OFFSET, CHANNEL_SIZE );
+
+                if (s->in_datalen <= 0) {
+                    D("ignoring %s packet from serial port",
+                      s->in_datalen ? "empty" : "malformed");
+                    s->in_datalen = 0;
+                }
+
+                //D("received %d bytes packet for channel %d", s->in_datalen, s->in_channel);
+                inpos = 0;
+            }
+        }
+        else /* then, populate the packet itself */
+        {
+            int   wanted = s->in_datalen - inpos;
+
+            if (avail > wanted)
+                avail = wanted;
+
+            memcpy( inp->data + inpos, p->data + rpos, avail );
+            inpos += avail;
+            rpos  += avail;
+
+            if (inpos == s->in_datalen) {
+                if (s->in_channel < 0) {
+                    D("ignoring %d bytes addressed to channel %d",
+                       inpos, s->in_channel);
+                } else {
+                    inp->len     = inpos;
+                    inp->channel = s->in_channel;
+                    receiver_post( s->receiver, inp );
+                    s->in_packet  = inp = packet_alloc();
+                }
+                s->in_datalen = 0;
+                inpos         = 0;
+            }
+        }
+    }
+    s->in_len = inpos;
+    packet_free(&p);
+}
+
+
+/* send a packet to the serial port.
+ * this assumes that p->len and p->channel contain the payload's
+ * size and channel and will add the appropriate header.
+ */
+static void
+serial_send( Serial*  s, Packet*  p )
+{
+    Packet*  h = packet_alloc();
+
+    //D("sending to serial %d bytes from channel %d: '%.*s'", p->len, p->channel, p->len, p->data);
+
+    /* insert a small header before this packet */
+    h->len = HEADER_SIZE;
+    int2hex( p->len,     h->data + LENGTH_OFFSET,  LENGTH_SIZE );
+    int2hex( p->channel, h->data + CHANNEL_OFFSET, CHANNEL_SIZE );
+
+    serial_dump( h, __FUNCTION__ );
+    serial_dump( p, __FUNCTION__ );
+
+    fdhandler_enqueue( s->fdhandler, h );
+    fdhandler_enqueue( s->fdhandler, p );
+}
+
+
+/* initialize serial reader */
+static void
+serial_init( Serial*         s,
+             int             fd,
+             FDHandlerList*  list,
+             Receiver*       receiver )
+{
+    Receiver  recv;
+
+    recv.user  = s;
+    recv.post  = (PostFunc)  serial_fd_receive;
+    recv.close = (CloseFunc) serial_fd_close;
+
+    s->receiver[0] = receiver[0];
+
+    s->fdhandler = fdhandler_new( fd, list, &recv );
+    s->in_len     = 0;
+    s->in_datalen = 0;
+    s->in_channel = 0;
+    s->in_packet  = packet_alloc();
+}
+
+
+/** CLIENTS
+ **/
+
+typedef struct Client       Client;
+typedef struct Multiplexer  Multiplexer;
+
+/* A Client object models a single qemud client socket
+ * connection in the emulated system.
+ *
+ * the client first sends the name of the system service
+ * it wants to contact (no framing), then waits for a 2
+ * byte answer from qemud.
+ *
+ * the answer is either "OK" or "KO" to indicate
+ * success or failure.
+ *
+ * In case of success, the client can send messages
+ * to the service.
+ *
+ * In case of failure, it can disconnect or try sending
+ * the name of another service.
+ */
+struct Client {
+    Client*       next;
+    Client**      pref;
+    int           channel;
+    char          registered;
+    FDHandler*    fdhandler;
+    Multiplexer*  multiplexer;
+};
+
+struct Multiplexer {
+    Client*        clients;
+    int            last_channel;
+    Serial         serial[1];
+    Looper         looper[1];
+    FDHandlerList  fdhandlers[1];
+};
+
+
+static int   multiplexer_open_channel( Multiplexer*  mult, Packet*  p );
+static void  multiplexer_close_channel( Multiplexer*  mult, int  channel );
+static void  multiplexer_serial_send( Multiplexer* mult, int  channel, Packet*  p );
+
+static void
+client_dump( Client*  c, Packet*  p, const char*  funcname )
+{
+    T("%s: client %p (%d): %3d bytes: '%s'",
+      funcname, c, c->fdhandler->fd,
+      p->len, quote(p->data, p->len));
+}
+
+/* destroy a client */
+static void
+client_free( Client*  c )
+{
+    /* remove from list */
+    c->pref[0] = c->next;
+    if (c->next)
+        c->next->pref = c->pref;
+
+    c->channel    = -1;
+    c->registered = 0;
+
+    /* gently ask the FDHandler to shutdown to
+     * avoid losing queued outgoing packets */
+    if (c->fdhandler != NULL) {
+        fdhandler_shutdown(c->fdhandler);
+        c->fdhandler = NULL;
+    }
+
+    xfree(c);
+}
+
+
+/* a function called when a client socket receives data */
+static void
+client_fd_receive( Client*  c, Packet*  p )
+{
+    client_dump(c, p, __FUNCTION__);
+
+    if (c->registered) {
+        /* the client is registered, just send the
+         * data through the serial port
+         */
+        multiplexer_serial_send(c->multiplexer, c->channel, p);
+        return;
+    }
+
+    if (c->channel > 0) {
+        /* the client is waiting registration results.
+         * this should not happen because the client
+         * should wait for our 'ok' or 'ko'.
+         * close the connection.
+         */
+         D("%s: bad client sending data before end of registration",
+           __FUNCTION__);
+     BAD_CLIENT:
+         packet_free(&p);
+         client_free(c);
+         return;
+    }
+
+    /* the client hasn't registered a service yet,
+     * so this must be the name of a service, call
+     * the multiplexer to start registration for
+     * it.
+     */
+    D("%s: attempting registration for service '%.*s'",
+      __FUNCTION__, p->len, p->data);
+    c->channel = multiplexer_open_channel(c->multiplexer, p);
+    if (c->channel < 0) {
+        D("%s: service name too long", __FUNCTION__);
+        goto BAD_CLIENT;
+    }
+    D("%s:    -> received channel id %d", __FUNCTION__, c->channel);
+    packet_free(&p);
+}
+
+
+/* a function called when the client socket is closed. */
+static void
+client_fd_close( Client*  c )
+{
+    T("%s: client %p (%d)", __FUNCTION__, c, c->fdhandler->fd);
+
+    /* no need to shutdown the FDHandler */
+    c->fdhandler = NULL;
+
+    /* tell the emulator we're out */
+    if (c->channel > 0)
+        multiplexer_close_channel(c->multiplexer, c->channel);
+
+    /* free the client */
+    client_free(c);
+}
+
+/* a function called when the multiplexer received a registration
+ * response from the emulator for a given client.
+ */
+static void
+client_registration( Client*  c, int  registered )
+{
+    Packet*  p = packet_alloc();
+
+    /* sends registration status to client */
+    if (!registered) {
+        D("%s: registration failed for client %d", __FUNCTION__, c->channel);
+        memcpy( p->data, "KO", 2 );
+        p->len = 2;
+    } else {
+        D("%s: registration succeeded for client %d", __FUNCTION__, c->channel);
+        memcpy( p->data, "OK", 2 );
+        p->len = 2;
+    }
+    client_dump(c, p, __FUNCTION__);
+    fdhandler_enqueue(c->fdhandler, p);
+
+    /* now save registration state
+     */
+    c->registered = registered;
+    if (!registered) {
+        /* allow the client to try registering another service */
+        c->channel = -1;
+    }
+}
+
+/* send data to a client */
+static void
+client_send( Client*  c, Packet*  p )
+{
+    client_dump(c, p, __FUNCTION__);
+    fdhandler_enqueue(c->fdhandler, p);
+}
+
+
+/* Create new client socket handler */
+static Client*
+client_new( Multiplexer*    mult,
+            int             fd,
+            FDHandlerList*  pfdhandlers,
+            Client**        pclients )
+{
+    Client*   c;
+    Receiver  recv;
+
+    xnew(c);
+
+    c->multiplexer = mult;
+    c->next        = NULL;
+    c->pref        = &c->next;
+    c->channel     = -1;
+    c->registered  = 0;
+
+    recv.user  = c;
+    recv.post  = (PostFunc)  client_fd_receive;
+    recv.close = (CloseFunc) client_fd_close;
+
+    c->fdhandler = fdhandler_new( fd, pfdhandlers, &recv );
+
+    /* add to client list */
+    c->next   = *pclients;
+    c->pref   = pclients;
+    *pclients = c;
+    if (c->next)
+        c->next->pref = &c->next;
+
+    return c;
+}
+
+/**  GLOBAL MULTIPLEXER
+ **/
+
+/* find a client by its channel */
+static Client*
+multiplexer_find_client( Multiplexer*  mult, int  channel )
+{
+    Client* c = mult->clients;
+
+    for ( ; c != NULL; c = c->next ) {
+        if (c->channel == channel)
+            return c;
+    }
+    return NULL;
+}
+
+/* handle control messages coming from the serial port
+ * on CONTROL_CHANNEL.
+ */
+static void
+multiplexer_handle_control( Multiplexer*  mult, Packet*  p )
+{
+    /* connection registration success */
+    if (p->len == 13 && !memcmp(p->data, "ok:connect:", 11)) {
+        int      channel = hex2int(p->data+11, 2);
+        Client*  client  = multiplexer_find_client(mult, channel);
+
+        /* note that 'client' can be NULL if the corresponding
+         * socket was closed before the emulator response arrived.
+         */
+        if (client != NULL) {
+            client_registration(client, 1);
+        } else {
+            D("%s: NULL client: '%.*s'", __FUNCTION__, p->len, p->data+11);
+        }
+        goto EXIT;
+    }
+
+    /* connection registration failure */
+    if (p->len == 13 && !memcmp(p->data, "ko:connect:",11)) {
+        int     channel = hex2int(p->data+11, 2);
+        Client* client  = multiplexer_find_client(mult, channel);
+
+        if (client != NULL)
+            client_registration(client, 0);
+
+        goto EXIT;
+    }
+
+    /* emulator-induced client disconnection */
+    if (p->len == 13 && !memcmp(p->data, "disconnect:",11)) {
+        int      channel = hex2int(p->data+11, 2);
+        Client*  client  = multiplexer_find_client(mult, channel);
+
+        if (client != NULL)
+            client_free(client);
+
+        goto EXIT;
+    }
+
+    /* A message that begins with "X00" is a probe sent by
+     * the emulator used to detect which version of qemud it runs
+     * against (in order to detect 1.0/1.1 system images. Just
+     * silently ignore it there instead of printing an error
+     * message.
+     */
+    if (p->len >= 3 && !memcmp(p->data,"X00",3)) {
+        goto EXIT;
+    }
+
+    D("%s: unknown control message (%d bytes): '%.*s'",
+      __FUNCTION__, p->len, p->len, p->data);
+
+EXIT:
+    packet_free(&p);
+}
+
+/* a function called when an incoming packet comes from the serial port */
+static void
+multiplexer_serial_receive( Multiplexer*  mult, Packet*  p )
+{
+    Client*  client;
+
+    T("%s: channel=%d '%.*s'", __FUNCTION__, p->channel, p->len, p->data);
+
+    if (p->channel == CHANNEL_CONTROL) {
+        multiplexer_handle_control(mult, p);
+        return;
+    }
+
+    client = multiplexer_find_client(mult, p->channel);
+    if (client != NULL) {
+        client_send(client, p);
+        return;
+    }
+
+    D("%s: discarding packet for unknown channel %d", __FUNCTION__, p->channel);
+    packet_free(&p);
+}
+
+/* a function called when the serial reader closes */
+static void
+multiplexer_serial_close( Multiplexer*  mult )
+{
+    fatal("unexpected close of serial reader");
+}
+
+/* a function called to send a packet to the serial port */
+static void
+multiplexer_serial_send( Multiplexer*  mult, int  channel, Packet*  p )
+{
+    p->channel = channel;
+    serial_send( mult->serial, p );
+}
+
+
+
+/* a function used by a client to allocate a new channel id and
+ * ask the emulator to open it. 'service' must be a packet containing
+ * the name of the service in its payload.
+ *
+ * returns -1 if the service name is too long.
+ *
+ * notice that client_registration() will be called later when
+ * the answer arrives.
+ */
+static int
+multiplexer_open_channel( Multiplexer*  mult, Packet*  service )
+{
+    Packet*   p = packet_alloc();
+    int       len, channel;
+
+    /* find a free channel number, assume we don't have many
+     * clients here. */
+    {
+        Client*  c;
+    TRY_AGAIN:
+        channel = (++mult->last_channel) & 0xff;
+
+        for (c = mult->clients; c != NULL; c = c->next)
+            if (c->channel == channel)
+                goto TRY_AGAIN;
+    }
+
+    len = snprintf((char*)p->data, sizeof p->data, "connect:%.*s:%02x", service->len, service->data, channel);
+    if (len >= (int)sizeof(p->data)) {
+        D("%s: weird, service name too long (%d > %d)", __FUNCTION__, len, sizeof(p->data));
+        packet_free(&p);
+        return -1;
+    }
+    p->channel = CHANNEL_CONTROL;
+    p->len     = len;
+
+    serial_send(mult->serial, p);
+    return channel;
+}
+
+/* used to tell the emulator a channel was closed by a client */
+static void
+multiplexer_close_channel( Multiplexer*  mult, int  channel )
+{
+    Packet*  p   = packet_alloc();
+    int      len = snprintf((char*)p->data, sizeof(p->data), "disconnect:%02x", channel);
+
+    if (len > (int)sizeof(p->data)) {
+        /* should not happen */
+        return;
+    }
+
+    p->channel = CHANNEL_CONTROL;
+    p->len     = len;
+
+    serial_send(mult->serial, p);
+}
+
+/* this function is used when a new connection happens on the control
+ * socket.
+ */
+static void
+multiplexer_control_accept( Multiplexer*  m, Packet*  p )
+{
+    /* the file descriptor for the new socket connection is
+     * in p->channel. See fdhandler_accept_event() */
+    int      fd     = p->channel;
+    Client*  client = client_new( m, fd, m->fdhandlers, &m->clients );
+
+    D("created client %p listening on fd %d", client, fd);
+
+    /* free dummy packet */
+    packet_free(&p);
+}
+
+static void
+multiplexer_control_close( Multiplexer*  m )
+{
+    fatal("unexpected multiplexer control close");
+}
+
+static void
+multiplexer_init( Multiplexer*  m, const char*  serial_dev )
+{
+    int       fd, control_fd;
+    Receiver  recv;
+
+    /* initialize looper and fdhandlers list */
+    looper_init( m->looper );
+    fdhandler_list_init( m->fdhandlers, m->looper );
+
+    /* open the serial port */
+    do {
+        fd = open(serial_dev, O_RDWR);
+    } while (fd < 0 && errno == EINTR);
+
+    if (fd < 0) {
+        fatal( "%s: could not open '%s': %s", __FUNCTION__, serial_dev,
+               strerror(errno) );
+    }
+    // disable echo on serial lines
+    if ( !memcmp( serial_dev, "/dev/ttyS", 9 ) ) {
+        struct termios  ios;
+        tcgetattr( fd, &ios );
+        ios.c_lflag = 0;  /* disable ECHO, ICANON, etc... */
+        tcsetattr( fd, TCSANOW, &ios );
+    }
+
+    /* initialize the serial reader/writer */
+    recv.user  = m;
+    recv.post  = (PostFunc)  multiplexer_serial_receive;
+    recv.close = (CloseFunc) multiplexer_serial_close;
+
+    serial_init( m->serial, fd, m->fdhandlers, &recv );
+
+    /* open the qemud control socket */
+    recv.user  = m;
+    recv.post  = (PostFunc)  multiplexer_control_accept;
+    recv.close = (CloseFunc) multiplexer_control_close;
+
+    fd = android_get_control_socket(CONTROL_SOCKET_NAME);
+    if (fd < 0) {
+        fatal("couldn't get fd for control socket '%s'", CONTROL_SOCKET_NAME);
+    }
+
+    fdhandler_new_accept( fd, m->fdhandlers, &recv );
+
+    /* initialize clients list */
+    m->clients = NULL;
+}
+
+/** MAIN LOOP
+ **/
+
+static Multiplexer  _multiplexer[1];
+
+int  main( void )
+{
+    Multiplexer*  m = _multiplexer;
+
+   /* extract the name of our serial device from the kernel
+    * boot options that are stored in /proc/cmdline
+    */
+#define  KERNEL_OPTION  "android.qemud="
+
+    {
+        char          buff[1024];
+        int           fd, len;
+        char*         p;
+        char*         q;
+
+        fd = open( "/proc/cmdline", O_RDONLY );
+        if (fd < 0) {
+            D("%s: can't open /proc/cmdline !!: %s", __FUNCTION__,
+            strerror(errno));
+            exit(1);
+        }
+
+        len = fd_read( fd, buff, sizeof(buff)-1 );
+        close(fd);
+        if (len < 0) {
+            D("%s: can't read /proc/cmdline: %s", __FUNCTION__,
+            strerror(errno));
+            exit(1);
+        }
+        buff[len] = 0;
+
+        p = strstr( buff, KERNEL_OPTION );
+        if (p == NULL) {
+            D("%s: can't find '%s' in /proc/cmdline",
+            __FUNCTION__, KERNEL_OPTION );
+            exit(1);
+        }
+
+        p += sizeof(KERNEL_OPTION)-1;  /* skip option */
+        q  = p;
+        while ( *q && *q != ' ' && *q != '\t' )
+            q += 1;
+
+        snprintf( buff, sizeof(buff), "/dev/%.*s", q-p, p );
+
+        multiplexer_init( m, buff );
+    }
+
+    D( "entering main loop");
+    looper_loop( m->looper );
+    D( "unexpected termination !!" );
+    return 0;
+}
diff --git a/sensors/Android.mk b/sensors/Android.mk
new file mode 100644
index 0000000..a1b8967
--- /dev/null
+++ b/sensors/Android.mk
@@ -0,0 +1,30 @@
+# Copyright (C) 2009 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.
+
+
+LOCAL_PATH := $(call my-dir)
+
+# HAL module implemenation stored in
+# hw/<SENSORS_HARDWARE_MODULE_ID>.<ro.hardware>.so
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
+LOCAL_SHARED_LIBRARIES := liblog libcutils
+LOCAL_SRC_FILES := sensors_qemu.c
+ifeq ($(TARGET_PRODUCT),vbox_x86)
+LOCAL_MODULE := sensors.vbox_x86
+else
+LOCAL_MODULE := sensors.goldfish
+endif
+include $(BUILD_SHARED_LIBRARY)
diff --git a/sensors/sensors_qemu.c b/sensors/sensors_qemu.c
new file mode 100644
index 0000000..9636ceb
--- /dev/null
+++ b/sensors/sensors_qemu.c
@@ -0,0 +1,636 @@
+/*
+ * Copyright (C) 2009 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.
+ */
+
+/* this implements a sensors hardware library for the Android emulator.
+ * the following code should be built as a shared library that will be
+ * placed into /system/lib/hw/sensors.goldfish.so
+ *
+ * it will be loaded by the code in hardware/libhardware/hardware.c
+ * which is itself called from com_android_server_SensorService.cpp
+ */
+
+
+/* we connect with the emulator through the "sensors" qemud service
+ */
+#define  SENSORS_SERVICE_NAME "sensors"
+
+#define LOG_TAG "QemuSensors"
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <cutils/log.h>
+#include <cutils/native_handle.h>
+#include <cutils/sockets.h>
+#include <hardware/sensors.h>
+
+#if 0
+#define  D(...)  ALOGD(__VA_ARGS__)
+#else
+#define  D(...)  ((void)0)
+#endif
+
+#define  E(...)  ALOGE(__VA_ARGS__)
+
+#include <hardware/qemud.h>
+
+/** SENSOR IDS AND NAMES
+ **/
+
+#define MAX_NUM_SENSORS 5
+
+#define SUPPORTED_SENSORS  ((1<<MAX_NUM_SENSORS)-1)
+
+#define  ID_BASE           SENSORS_HANDLE_BASE
+#define  ID_ACCELERATION   (ID_BASE+0)
+#define  ID_MAGNETIC_FIELD (ID_BASE+1)
+#define  ID_ORIENTATION    (ID_BASE+2)
+#define  ID_TEMPERATURE    (ID_BASE+3)
+#define  ID_PROXIMITY      (ID_BASE+4)
+
+#define  SENSORS_ACCELERATION   (1 << ID_ACCELERATION)
+#define  SENSORS_MAGNETIC_FIELD  (1 << ID_MAGNETIC_FIELD)
+#define  SENSORS_ORIENTATION     (1 << ID_ORIENTATION)
+#define  SENSORS_TEMPERATURE     (1 << ID_TEMPERATURE)
+#define  SENSORS_PROXIMITY       (1 << ID_PROXIMITY)
+
+#define  ID_CHECK(x)  ((unsigned)((x)-ID_BASE) < MAX_NUM_SENSORS)
+
+#define  SENSORS_LIST  \
+    SENSOR_(ACCELERATION,"acceleration") \
+    SENSOR_(MAGNETIC_FIELD,"magnetic-field") \
+    SENSOR_(ORIENTATION,"orientation") \
+    SENSOR_(TEMPERATURE,"temperature") \
+    SENSOR_(PROXIMITY,"proximity") \
+
+static const struct {
+    const char*  name;
+    int          id; } _sensorIds[MAX_NUM_SENSORS] =
+{
+#define SENSOR_(x,y)  { y, ID_##x },
+    SENSORS_LIST
+#undef  SENSOR_
+};
+
+static const char*
+_sensorIdToName( int  id )
+{
+    int  nn;
+    for (nn = 0; nn < MAX_NUM_SENSORS; nn++)
+        if (id == _sensorIds[nn].id)
+            return _sensorIds[nn].name;
+    return "<UNKNOWN>";
+}
+
+static int
+_sensorIdFromName( const char*  name )
+{
+    int  nn;
+
+    if (name == NULL)
+        return -1;
+
+    for (nn = 0; nn < MAX_NUM_SENSORS; nn++)
+        if (!strcmp(name, _sensorIds[nn].name))
+            return _sensorIds[nn].id;
+
+    return -1;
+}
+
+/** SENSORS POLL DEVICE
+ **
+ ** This one is used to read sensor data from the hardware.
+ ** We implement this by simply reading the data from the
+ ** emulator through the QEMUD channel.
+ **/
+
+typedef struct SensorPoll {
+    struct sensors_poll_device_t  device;
+    sensors_event_t               sensors[MAX_NUM_SENSORS];
+    int                           events_fd;
+    uint32_t                      pendingSensors;
+    int64_t                       timeStart;
+    int64_t                       timeOffset;
+    int                           fd;
+    uint32_t                      active_sensors;
+} SensorPoll;
+
+/* this must return a file descriptor that will be used to read
+ * the sensors data (it is passed to data__data_open() below
+ */
+static native_handle_t*
+control__open_data_source(struct sensors_poll_device_t *dev)
+{
+    SensorPoll*  ctl = (void*)dev;
+    native_handle_t* handle;
+
+    if (ctl->fd < 0) {
+        ctl->fd = qemud_channel_open(SENSORS_SERVICE_NAME);
+    }
+    D("%s: fd=%d", __FUNCTION__, ctl->fd);
+    handle = native_handle_create(1, 0);
+    handle->data[0] = dup(ctl->fd);
+    return handle;
+}
+
+static int
+control__activate(struct sensors_poll_device_t *dev,
+                  int handle,
+                  int enabled)
+{
+    SensorPoll*     ctl = (void*)dev;
+    uint32_t        mask, sensors, active, new_sensors, changed;
+    char            command[128];
+    int             ret;
+
+    D("%s: handle=%s (%d) fd=%d enabled=%d", __FUNCTION__,
+        _sensorIdToName(handle), handle, ctl->fd, enabled);
+
+    if (!ID_CHECK(handle)) {
+        E("%s: bad handle ID", __FUNCTION__);
+        return -1;
+    }
+
+    mask    = (1<<handle);
+    sensors = enabled ? mask : 0;
+
+    active      = ctl->active_sensors;
+    new_sensors = (active & ~mask) | (sensors & mask);
+    changed     = active ^ new_sensors;
+
+    if (!changed)
+        return 0;
+
+    snprintf(command, sizeof command, "set:%s:%d",
+                _sensorIdToName(handle), enabled != 0);
+
+    if (ctl->fd < 0) {
+        ctl->fd = qemud_channel_open(SENSORS_SERVICE_NAME);
+    }
+
+    ret = qemud_channel_send(ctl->fd, command, -1);
+    if (ret < 0) {
+        E("%s: when sending command errno=%d: %s", __FUNCTION__, errno, strerror(errno));
+        return -1;
+    }
+    ctl->active_sensors = new_sensors;
+
+    return 0;
+}
+
+static int
+control__set_delay(struct sensors_poll_device_t *dev, int32_t ms)
+{
+    SensorPoll*     ctl = (void*)dev;
+    char            command[128];
+
+    D("%s: dev=%p delay-ms=%d", __FUNCTION__, dev, ms);
+
+    snprintf(command, sizeof command, "set-delay:%d", ms);
+
+    return qemud_channel_send(ctl->fd, command, -1);
+}
+
+static int
+control__close(struct hw_device_t *dev)
+{
+    SensorPoll*  ctl = (void*)dev;
+    close(ctl->fd);
+    free(ctl);
+    return 0;
+}
+
+/* return the current time in nanoseconds */
+static int64_t
+data__now_ns(void)
+{
+    struct timespec  ts;
+
+    clock_gettime(CLOCK_MONOTONIC, &ts);
+
+    return (int64_t)ts.tv_sec * 1000000000 + ts.tv_nsec;
+}
+
+static int
+data__data_open(struct sensors_poll_device_t *dev, native_handle_t* handle)
+{
+    SensorPoll*  data = (void*)dev;
+    int i;
+    D("%s: dev=%p fd=%d", __FUNCTION__, dev, handle->data[0]);
+    memset(&data->sensors, 0, sizeof(data->sensors));
+
+    data->pendingSensors = 0;
+    data->timeStart      = 0;
+    data->timeOffset     = 0;
+
+    data->events_fd = dup(handle->data[0]);
+    D("%s: dev=%p fd=%d (was %d)", __FUNCTION__, dev, data->events_fd, handle->data[0]);
+    native_handle_close(handle);
+    native_handle_delete(handle);
+    return 0;
+}
+
+static int
+data__data_close(struct sensors_poll_device_t *dev)
+{
+    SensorPoll*  data = (void*)dev;
+    D("%s: dev=%p", __FUNCTION__, dev);
+    if (data->events_fd >= 0) {
+        close(data->events_fd);
+        data->events_fd = -1;
+    }
+    return 0;
+}
+
+static int
+pick_sensor(SensorPoll*       data,
+            sensors_event_t*  values)
+{
+    uint32_t mask = SUPPORTED_SENSORS;
+    while (mask) {
+        uint32_t i = 31 - __builtin_clz(mask);
+        mask &= ~(1<<i);
+        if (data->pendingSensors & (1<<i)) {
+            data->pendingSensors &= ~(1<<i);
+            *values = data->sensors[i];
+            values->sensor = i;
+            values->version = sizeof(*values);
+
+            D("%s: %d [%f, %f, %f]", __FUNCTION__,
+                    i,
+                    values->data[0],
+                    values->data[1],
+                    values->data[2]);
+            return i;
+        }
+    }
+    ALOGE("No sensor to return!!! pendingSensors=%08x", data->pendingSensors);
+    // we may end-up in a busy loop, slow things down, just in case.
+    usleep(100000);
+    return -EINVAL;
+}
+
+static int
+data__poll(struct sensors_poll_device_t *dev, sensors_event_t* values)
+{
+    SensorPoll*  data = (void*)dev;
+    int fd = data->events_fd;
+
+    D("%s: data=%p", __FUNCTION__, dev);
+
+    // there are pending sensors, returns them now...
+    if (data->pendingSensors) {
+        return pick_sensor(data, values);
+    }
+
+    // wait until we get a complete event for an enabled sensor
+    uint32_t new_sensors = 0;
+
+    while (1) {
+        /* read the next event */
+        char     buff[256];
+        int      len = qemud_channel_recv(data->events_fd, buff, sizeof buff-1);
+        float    params[3];
+        int64_t  event_time;
+
+        if (len < 0) {
+            E("%s: len=%d, errno=%d: %s", __FUNCTION__, len, errno, strerror(errno));
+            return -errno;
+        }
+
+        buff[len] = 0;
+
+        /* "wake" is sent from the emulator to exit this loop. */
+        if (!strcmp((const char*)data, "wake")) {
+            return 0x7FFFFFFF;
+        }
+
+        /* "acceleration:<x>:<y>:<z>" corresponds to an acceleration event */
+        if (sscanf(buff, "acceleration:%g:%g:%g", params+0, params+1, params+2) == 3) {
+            new_sensors |= SENSORS_ACCELERATION;
+            data->sensors[ID_ACCELERATION].acceleration.x = params[0];
+            data->sensors[ID_ACCELERATION].acceleration.y = params[1];
+            data->sensors[ID_ACCELERATION].acceleration.z = params[2];
+            continue;
+        }
+
+        /* "orientation:<azimuth>:<pitch>:<roll>" is sent when orientation changes */
+        if (sscanf(buff, "orientation:%g:%g:%g", params+0, params+1, params+2) == 3) {
+            new_sensors |= SENSORS_ORIENTATION;
+            data->sensors[ID_ORIENTATION].orientation.azimuth = params[0];
+            data->sensors[ID_ORIENTATION].orientation.pitch   = params[1];
+            data->sensors[ID_ORIENTATION].orientation.roll    = params[2];
+            data->sensors[ID_ORIENTATION].orientation.status  = SENSOR_STATUS_ACCURACY_HIGH;
+            continue;
+        }
+
+        /* "magnetic:<x>:<y>:<z>" is sent for the params of the magnetic field */
+        if (sscanf(buff, "magnetic:%g:%g:%g", params+0, params+1, params+2) == 3) {
+            new_sensors |= SENSORS_MAGNETIC_FIELD;
+            data->sensors[ID_MAGNETIC_FIELD].magnetic.x = params[0];
+            data->sensors[ID_MAGNETIC_FIELD].magnetic.y = params[1];
+            data->sensors[ID_MAGNETIC_FIELD].magnetic.z = params[2];
+            data->sensors[ID_MAGNETIC_FIELD].magnetic.status = SENSOR_STATUS_ACCURACY_HIGH;
+            continue;
+        }
+
+        /* "temperature:<celsius>" */
+        if (sscanf(buff, "temperature:%g", params+0) == 1) {
+            new_sensors |= SENSORS_TEMPERATURE;
+            data->sensors[ID_TEMPERATURE].temperature = params[0];
+            continue;
+        }
+
+        /* "proximity:<value>" */
+        if (sscanf(buff, "proximity:%g", params+0) == 1) {
+            new_sensors |= SENSORS_PROXIMITY;
+            data->sensors[ID_PROXIMITY].distance = params[0];
+            continue;
+        }
+
+        /* "sync:<time>" is sent after a series of sensor events.
+         * where 'time' is expressed in micro-seconds and corresponds
+         * to the VM time when the real poll occured.
+         */
+        if (sscanf(buff, "sync:%lld", &event_time) == 1) {
+            if (new_sensors) {
+                data->pendingSensors = new_sensors;
+                int64_t t = event_time * 1000LL;  /* convert to nano-seconds */
+
+                /* use the time at the first sync: as the base for later
+                 * time values */
+                if (data->timeStart == 0) {
+                    data->timeStart  = data__now_ns();
+                    data->timeOffset = data->timeStart - t;
+                }
+                t += data->timeOffset;
+
+                while (new_sensors) {
+                    uint32_t i = 31 - __builtin_clz(new_sensors);
+                    new_sensors &= ~(1<<i);
+                    data->sensors[i].timestamp = t;
+                }
+                return pick_sensor(data, values);
+            } else {
+                D("huh ? sync without any sensor data ?");
+            }
+            continue;
+        }
+        D("huh ? unsupported command");
+    }
+    return -1;
+}
+
+static int
+data__close(struct hw_device_t *dev)
+{
+    SensorPoll* data = (SensorPoll*)dev;
+    if (data) {
+        if (data->events_fd >= 0) {
+            //ALOGD("(device close) about to close fd=%d", data->events_fd);
+            close(data->events_fd);
+        }
+        free(data);
+    }
+    return 0;
+}
+
+/** SENSORS POLL DEVICE FUNCTIONS **/
+
+static int poll__close(struct hw_device_t* dev)
+{
+    SensorPoll*  ctl = (void*)dev;
+    close(ctl->fd);
+    if (ctl->fd >= 0) {
+        close(ctl->fd);
+    }
+    if (ctl->events_fd >= 0) {
+        close(ctl->events_fd);
+    }
+    free(ctl);
+    return 0;
+}
+
+static int poll__poll(struct sensors_poll_device_t *dev,
+            sensors_event_t* data, int count)
+{
+    SensorPoll*  datadev = (void*)dev;
+    int ret;
+    int i;
+    D("%s: dev=%p data=%p count=%d ", __FUNCTION__, dev, data, count);
+
+    for (i = 0; i < count; i++)  {
+        ret = data__poll(dev, data);
+        data++;
+        if (ret > MAX_NUM_SENSORS || ret < 0) {
+           return i;
+        }
+        if (!datadev->pendingSensors) {
+           return i + 1;
+        }
+    }
+    return count;
+}
+
+static int poll__activate(struct sensors_poll_device_t *dev,
+            int handle, int enabled)
+{
+    int ret;
+    native_handle_t* hdl;
+    SensorPoll*  ctl = (void*)dev;
+    D("%s: dev=%p handle=%x enable=%d ", __FUNCTION__, dev, handle, enabled);
+    if (ctl->fd < 0) {
+        D("%s: OPEN CTRL and DATA ", __FUNCTION__);
+        hdl = control__open_data_source(dev);
+        ret = data__data_open(dev,hdl);
+    }
+    ret = control__activate(dev, handle, enabled);
+    return ret;
+}
+
+static int poll__setDelay(struct sensors_poll_device_t *dev,
+            int handle, int64_t ns)
+{
+    // TODO
+    return 0;
+}
+
+/** MODULE REGISTRATION SUPPORT
+ **
+ ** This is required so that hardware/libhardware/hardware.c
+ ** will dlopen() this library appropriately.
+ **/
+
+/*
+ * the following is the list of all supported sensors.
+ * this table is used to build sSensorList declared below
+ * according to which hardware sensors are reported as
+ * available from the emulator (see get_sensors_list below)
+ *
+ * note: numerical values for maxRange/resolution/power were
+ *       taken from the reference AK8976A implementation
+ */
+static const struct sensor_t sSensorListInit[] = {
+        { .name       = "Goldfish 3-axis Accelerometer",
+          .vendor     = "The Android Open Source Project",
+          .version    = 1,
+          .handle     = ID_ACCELERATION,
+          .type       = SENSOR_TYPE_ACCELEROMETER,
+          .maxRange   = 2.8f,
+          .resolution = 1.0f/4032.0f,
+          .power      = 3.0f,
+          .reserved   = {}
+        },
+
+        { .name       = "Goldfish 3-axis Magnetic field sensor",
+          .vendor     = "The Android Open Source Project",
+          .version    = 1,
+          .handle     = ID_MAGNETIC_FIELD,
+          .type       = SENSOR_TYPE_MAGNETIC_FIELD,
+          .maxRange   = 2000.0f,
+          .resolution = 1.0f,
+          .power      = 6.7f,
+          .reserved   = {}
+        },
+
+        { .name       = "Goldfish Orientation sensor",
+          .vendor     = "The Android Open Source Project",
+          .version    = 1,
+          .handle     = ID_ORIENTATION,
+          .type       = SENSOR_TYPE_ORIENTATION,
+          .maxRange   = 360.0f,
+          .resolution = 1.0f,
+          .power      = 9.7f,
+          .reserved   = {}
+        },
+
+        { .name       = "Goldfish Temperature sensor",
+          .vendor     = "The Android Open Source Project",
+          .version    = 1,
+          .handle     = ID_TEMPERATURE,
+          .type       = SENSOR_TYPE_TEMPERATURE,
+          .maxRange   = 80.0f,
+          .resolution = 1.0f,
+          .power      = 0.0f,
+          .reserved   = {}
+        },
+
+        { .name       = "Goldfish Proximity sensor",
+          .vendor     = "The Android Open Source Project",
+          .version    = 1,
+          .handle     = ID_PROXIMITY,
+          .type       = SENSOR_TYPE_PROXIMITY,
+          .maxRange   = 1.0f,
+          .resolution = 1.0f,
+          .power      = 20.0f,
+          .reserved   = {}
+        },
+};
+
+static struct sensor_t  sSensorList[MAX_NUM_SENSORS];
+
+static int sensors__get_sensors_list(struct sensors_module_t* module,
+        struct sensor_t const** list)
+{
+    int  fd = qemud_channel_open(SENSORS_SERVICE_NAME);
+    char buffer[12];
+    int  mask, nn, count;
+
+    int  ret;
+    if (fd < 0) {
+        E("%s: no qemud connection", __FUNCTION__);
+        return 0;
+    }
+    ret = qemud_channel_send(fd, "list-sensors", -1);
+    if (ret < 0) {
+        E("%s: could not query sensor list: %s", __FUNCTION__,
+          strerror(errno));
+        close(fd);
+        return 0;
+    }
+    ret = qemud_channel_recv(fd, buffer, sizeof buffer-1);
+    if (ret < 0) {
+        E("%s: could not receive sensor list: %s", __FUNCTION__,
+          strerror(errno));
+        close(fd);
+        return 0;
+    }
+    buffer[ret] = 0;
+    close(fd);
+
+    /* the result is a integer used as a mask for available sensors */
+    mask  = atoi(buffer);
+    count = 0;
+    for (nn = 0; nn < MAX_NUM_SENSORS; nn++) {
+        if (((1 << nn) & mask) == 0)
+            continue;
+
+        sSensorList[count++] = sSensorListInit[nn];
+    }
+    D("%s: returned %d sensors (mask=%d)", __FUNCTION__, count, mask);
+    *list = sSensorList;
+    return count;
+}
+
+
+static int
+open_sensors(const struct hw_module_t* module,
+             const char*               name,
+             struct hw_device_t*      *device)
+{
+    int  status = -EINVAL;
+
+    D("%s: name=%s", __FUNCTION__, name);
+
+    if (!strcmp(name, SENSORS_HARDWARE_POLL)) {
+        SensorPoll *dev = malloc(sizeof(*dev));
+
+        memset(dev, 0, sizeof(*dev));
+
+        dev->device.common.tag     = HARDWARE_DEVICE_TAG;
+        dev->device.common.version = 0;
+        dev->device.common.module  = (struct hw_module_t*) module;
+        dev->device.common.close   = poll__close;
+        dev->device.poll           = poll__poll;
+        dev->device.activate       = poll__activate;
+        dev->device.setDelay       = poll__setDelay;
+        dev->events_fd             = -1;
+        dev->fd                    = -1;
+
+        *device = &dev->device.common;
+        status  = 0;
+    }
+    return status;
+}
+
+
+static struct hw_module_methods_t sensors_module_methods = {
+    .open = open_sensors
+};
+
+struct sensors_module_t HAL_MODULE_INFO_SYM = {
+    .common = {
+        .tag = HARDWARE_MODULE_TAG,
+        .version_major = 1,
+        .version_minor = 0,
+        .id = SENSORS_HARDWARE_MODULE_ID,
+        .name = "Goldfish SENSORS Module",
+        .author = "The Android Open Source Project",
+        .methods = &sensors_module_methods,
+    },
+    .get_sensors_list = sensors__get_sensors_list
+};