Initial import of VNCFlinger
diff --git a/src/EglWindow.cpp b/src/EglWindow.cpp
new file mode 100644
index 0000000..c534b02
--- /dev/null
+++ b/src/EglWindow.cpp
@@ -0,0 +1,189 @@
+/*
+ * Copyright 2013 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_TAG "VNC-EglWindow"
+//#define LOG_NDEBUG 0
+#include <utils/Log.h>
+
+#define EGL_EGLEXT_PROTOTYPES
+
+#include <gui/BufferQueue.h>
+#include <gui/GraphicBufferAlloc.h>
+#include <gui/Surface.h>
+
+#include "EglWindow.h"
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include <assert.h>
+
+using namespace android;
+
+
+status_t EglWindow::createWindow(const sp<IGraphicBufferProducer>& surface) {
+    if (mEglSurface != EGL_NO_SURFACE) {
+        ALOGE("surface already created");
+        return UNKNOWN_ERROR;
+    }
+    status_t err = eglSetupContext(false);
+    if (err != NO_ERROR) {
+        return err;
+    }
+
+    // Cache the current dimensions.  We're not expecting these to change.
+    surface->query(NATIVE_WINDOW_WIDTH, &mWidth);
+    surface->query(NATIVE_WINDOW_HEIGHT, &mHeight);
+
+    // Output side (EGL surface to draw on).
+    sp<ANativeWindow> anw = new Surface(surface);
+    mEglSurface = eglCreateWindowSurface(mEglDisplay, mEglConfig, anw.get(),
+            NULL);
+    if (mEglSurface == EGL_NO_SURFACE) {
+        ALOGE("eglCreateWindowSurface error: %#x", eglGetError());
+        eglRelease();
+        return UNKNOWN_ERROR;
+    }
+
+    return NO_ERROR;
+}
+
+status_t EglWindow::createPbuffer(int width, int height) {
+    if (mEglSurface != EGL_NO_SURFACE) {
+        ALOGE("surface already created");
+        return UNKNOWN_ERROR;
+    }
+    status_t err = eglSetupContext(true);
+    if (err != NO_ERROR) {
+        return err;
+    }
+
+    mWidth = width;
+    mHeight = height;
+
+    EGLint pbufferAttribs[] = {
+            EGL_WIDTH, width,
+            EGL_HEIGHT, height,
+            EGL_NONE
+    };
+    mEglSurface = eglCreatePbufferSurface(mEglDisplay, mEglConfig, pbufferAttribs);
+    if (mEglSurface == EGL_NO_SURFACE) {
+        ALOGE("eglCreatePbufferSurface error: %#x", eglGetError());
+        eglRelease();
+        return UNKNOWN_ERROR;
+    }
+
+    return NO_ERROR;
+}
+
+status_t EglWindow::makeCurrent() const {
+    if (!eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
+        ALOGE("eglMakeCurrent failed: %#x", eglGetError());
+        return UNKNOWN_ERROR;
+    }
+    return NO_ERROR;
+}
+
+status_t EglWindow::eglSetupContext(bool forPbuffer) {
+    EGLBoolean result;
+
+    mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    if (mEglDisplay == EGL_NO_DISPLAY) {
+        ALOGE("eglGetDisplay failed: %#x", eglGetError());
+        return UNKNOWN_ERROR;
+    }
+
+    EGLint majorVersion, minorVersion;
+    result = eglInitialize(mEglDisplay, &majorVersion, &minorVersion);
+    if (result != EGL_TRUE) {
+        ALOGE("eglInitialize failed: %#x", eglGetError());
+        return UNKNOWN_ERROR;
+    }
+    ALOGV("Initialized EGL v%d.%d", majorVersion, minorVersion);
+
+    EGLint numConfigs = 0;
+    EGLint windowConfigAttribs[] = {
+            EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+            EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+            EGL_RECORDABLE_ANDROID, 1,
+            EGL_RED_SIZE, 8,
+            EGL_GREEN_SIZE, 8,
+            EGL_BLUE_SIZE, 8,
+            EGL_ALPHA_SIZE, 8,
+    };
+    EGLint pbufferConfigAttribs[] = {
+            EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
+            EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+            EGL_RED_SIZE, 8,
+            EGL_GREEN_SIZE, 8,
+            EGL_BLUE_SIZE, 8,
+            EGL_ALPHA_SIZE, 8,
+            EGL_NONE
+    };
+    result = eglChooseConfig(mEglDisplay,
+            forPbuffer ? pbufferConfigAttribs : windowConfigAttribs,
+            &mEglConfig, 1, &numConfigs);
+    if (result != EGL_TRUE) {
+        ALOGE("eglChooseConfig error: %#x", eglGetError());
+        return UNKNOWN_ERROR;
+    }
+
+    EGLint contextAttribs[] = {
+        EGL_CONTEXT_CLIENT_VERSION, 2,
+        EGL_NONE
+    };
+    mEglContext = eglCreateContext(mEglDisplay, mEglConfig, EGL_NO_CONTEXT,
+            contextAttribs);
+    if (mEglContext == EGL_NO_CONTEXT) {
+        ALOGE("eglCreateContext error: %#x", eglGetError());
+        return UNKNOWN_ERROR;
+    }
+
+    return NO_ERROR;
+}
+
+void EglWindow::eglRelease() {
+    ALOGV("EglWindow::eglRelease");
+    if (mEglDisplay != EGL_NO_DISPLAY) {
+        eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
+                EGL_NO_CONTEXT);
+
+        if (mEglContext != EGL_NO_CONTEXT) {
+            eglDestroyContext(mEglDisplay, mEglContext);
+        }
+
+        if (mEglSurface != EGL_NO_SURFACE) {
+            eglDestroySurface(mEglDisplay, mEglSurface);
+        }
+    }
+
+    mEglDisplay = EGL_NO_DISPLAY;
+    mEglContext = EGL_NO_CONTEXT;
+    mEglSurface = EGL_NO_SURFACE;
+    mEglConfig = NULL;
+
+    eglReleaseThread();
+}
+
+// Sets the presentation time on the current EGL buffer.
+void EglWindow::presentationTime(nsecs_t whenNsec) const {
+    eglPresentationTimeANDROID(mEglDisplay, mEglSurface, whenNsec);
+}
+
+// Swaps the EGL buffer.
+void EglWindow::swapBuffers() const {
+    eglSwapBuffers(mEglDisplay, mEglSurface);
+}