RS Error cleanup.
Thow java exception during init if the
GL driver fails rather than native crash.

Change-Id: Ie96ef5a2ac12e64f9456545d86157c4c95179a8e
diff --git a/graphics/java/android/renderscript/RSDriverException.java b/graphics/java/android/renderscript/RSDriverException.java
new file mode 100644
index 0000000..61787e6
--- /dev/null
+++ b/graphics/java/android/renderscript/RSDriverException.java
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+package android.renderscript;
+
+
+/**
+ * Base class for all exceptions thrown by the Android
+ * Renderscript
+ * @hide
+ */
+public class RSDriverException extends RSRuntimeException {
+    public RSDriverException(String string) {
+        super(string);
+    }
+}
+
+
+
diff --git a/graphics/java/android/renderscript/RSIllegalArgumentException.java b/graphics/java/android/renderscript/RSIllegalArgumentException.java
new file mode 100644
index 0000000..8d67a8d
--- /dev/null
+++ b/graphics/java/android/renderscript/RSIllegalArgumentException.java
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+package android.renderscript;
+
+
+/**
+ * Base class for all exceptions thrown by the Android
+ * Renderscript
+ * @hide
+ */
+public class RSIllegalArgumentException extends RSRuntimeException {
+    public RSIllegalArgumentException(String string) {
+        super(string);
+    }
+}
+
+
diff --git a/graphics/java/android/renderscript/RSInvalidStateException.java b/graphics/java/android/renderscript/RSInvalidStateException.java
new file mode 100644
index 0000000..53b9479
--- /dev/null
+++ b/graphics/java/android/renderscript/RSInvalidStateException.java
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+package android.renderscript;
+
+
+/**
+ * Base class for all exceptions thrown by the Android
+ * Renderscript
+ * @hide
+ */
+public class RSInvalidStateException extends RSRuntimeException {
+    public RSInvalidStateException(String string) {
+        super(string);
+    }
+}
+
+
+
diff --git a/graphics/java/android/renderscript/RSRuntimeException.java b/graphics/java/android/renderscript/RSRuntimeException.java
new file mode 100644
index 0000000..4c97937
--- /dev/null
+++ b/graphics/java/android/renderscript/RSRuntimeException.java
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+package android.renderscript;
+
+
+/**
+ * Base class for all exceptions thrown by the Android
+ * Renderscript
+ * @hide
+ */
+public class RSRuntimeException
+  extends java.lang.RuntimeException {
+    public RSRuntimeException(String string) {
+        super(string);
+    }
+}
+
diff --git a/graphics/java/android/renderscript/RenderScriptGL.java b/graphics/java/android/renderscript/RenderScriptGL.java
index 5fe69cd..21cbb9a 100644
--- a/graphics/java/android/renderscript/RenderScriptGL.java
+++ b/graphics/java/android/renderscript/RenderScriptGL.java
@@ -128,6 +128,9 @@
                                     mSurfaceConfig.mStencilMin, mSurfaceConfig.mStencilPref,
                                     mSurfaceConfig.mSamplesMin, mSurfaceConfig.mSamplesPref,
                                     mSurfaceConfig.mSamplesQ);
+        if (mContext == 0) {
+            throw new RSDriverException("Failed to create RS context.");
+        }
         mMessageThread = new MessageThread(this);
         mMessageThread.start();
         Element.initPredefined(this);
diff --git a/graphics/java/android/renderscript/Type.java b/graphics/java/android/renderscript/Type.java
index caa8b13..9a40d1f 100644
--- a/graphics/java/android/renderscript/Type.java
+++ b/graphics/java/android/renderscript/Type.java
@@ -33,8 +33,6 @@
     int mElementCount;
     Element mElement;
 
-    Class mJavaClass;
-
     public Element getElement() {
         return mElement;
     }
@@ -124,12 +122,6 @@
         calcElementCount();
     }
 
-    public static Type createFromClass(RenderScript rs, Class c, int size, String scriptName) {
-        android.util.Log.e("RenderScript", "Calling depricated createFromClass");
-        return null;
-    }
-
-
     public static class Builder {
         RenderScript mRS;
         Dimension[] mDimensions;
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index 0241455..678d327 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -107,7 +107,7 @@
 }
 
 
-void Context::initGLThread()
+bool Context::initGLThread()
 {
     pthread_mutex_lock(&gInitMutex);
     LOGV("initGLThread start %p", this);
@@ -169,7 +169,9 @@
     mEGL.mContext = eglCreateContext(mEGL.mDisplay, mEGL.mConfig, EGL_NO_CONTEXT, context_attribs2);
     checkEglError("eglCreateContext");
     if (mEGL.mContext == EGL_NO_CONTEXT) {
+        pthread_mutex_unlock(&gInitMutex);
         LOGE("%p, eglCreateContext returned EGL_NO_CONTEXT", this);
+        return false;
     }
     gGLContextCount++;
 
@@ -179,10 +181,19 @@
     checkEglError("eglCreatePbufferSurface");
     if (mEGL.mSurfaceDefault == EGL_NO_SURFACE) {
         LOGE("eglCreatePbufferSurface returned EGL_NO_SURFACE");
+        pthread_mutex_unlock(&gInitMutex);
+        deinitEGL();
+        return false;
     }
 
     EGLBoolean ret = eglMakeCurrent(mEGL.mDisplay, mEGL.mSurfaceDefault, mEGL.mSurfaceDefault, mEGL.mContext);
-    checkEglError("eglMakeCurrent", ret);
+    if (ret == EGL_FALSE) {
+        LOGE("eglMakeCurrent returned EGL_FALSE");
+        checkEglError("eglMakeCurrent", ret);
+        pthread_mutex_unlock(&gInitMutex);
+        deinitEGL();
+        return false;
+    }
 
     mGL.mVersion = glGetString(GL_VERSION);
     mGL.mVendor = glGetString(GL_VENDOR);
@@ -207,6 +218,9 @@
 
     if (!verptr) {
         LOGE("Error, OpenGL ES Lite not supported");
+        pthread_mutex_unlock(&gInitMutex);
+        deinitEGL();
+        return false;
     } else {
         sscanf(verptr, " %i.%i", &mGL.mMajorVersion, &mGL.mMinorVersion);
     }
@@ -231,15 +245,18 @@
 
     LOGV("initGLThread end %p", this);
     pthread_mutex_unlock(&gInitMutex);
+    return true;
 }
 
 void Context::deinitEGL()
 {
     LOGV("%p, deinitEGL", this);
 
-    eglMakeCurrent(mEGL.mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, mEGL.mContext);
-    eglDestroyContext(mEGL.mDisplay, mEGL.mContext);
-    checkEglError("eglDestroyContext");
+    if (mEGL.mContext != EGL_NO_CONTEXT) {
+        eglMakeCurrent(mEGL.mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, mEGL.mContext);
+        eglDestroyContext(mEGL.mDisplay, mEGL.mContext);
+        checkEglError("eglDestroyContext");
+    }
 
     gGLContextCount--;
     if (!gGLContextCount) {
@@ -421,6 +438,7 @@
      rsc->mTlsStruct = new ScriptTLSStruct;
      if (!rsc->mTlsStruct) {
          LOGE("Error allocating tls storage");
+         rsc->setError(RS_ERROR_OUT_OF_MEMORY, "Failed allocation for TLS");
          return NULL;
      }
      rsc->mTlsStruct->mContext = rsc;
@@ -430,7 +448,10 @@
          LOGE("pthread_setspecific %i", status);
      }
 
-     rsc->initGLThread();
+     if (!rsc->initGLThread()) {
+         rsc->setError(RS_ERROR_OUT_OF_MEMORY, "Failed initializing GL");
+         return NULL;
+     }
 
      rsc->mScriptC.init(rsc);
      if (rsc->mIsGraphicsContext) {
@@ -580,18 +601,33 @@
 #endif
 }
 
-Context::Context(Device *dev, const RsSurfaceConfig *sc)
+Context::Context()
 {
-    pthread_mutex_lock(&gInitMutex);
-
-    dev->addContext(this);
-    mDev = dev;
+    mDev = NULL;
     mRunning = false;
     mExit = false;
     mPaused = false;
     mObjHead = NULL;
     mError = RS_ERROR_NONE;
     mErrorMsg = NULL;
+}
+
+Context * Context::createContext(Device *dev, const RsSurfaceConfig *sc)
+{
+    Context * rsc = new Context();
+    if (!rsc->initContext(dev, sc)) {
+        delete rsc;
+        return NULL;
+    }
+    return rsc;
+}
+
+bool Context::initContext(Device *dev, const RsSurfaceConfig *sc)
+{
+    pthread_mutex_lock(&gInitMutex);
+
+    dev->addContext(this);
+    mDev = dev;
     if (sc) {
         mUserSurfaceConfig = *sc;
     } else {
@@ -610,7 +646,7 @@
         if (status) {
             LOGE("Failed to init thread tls key.");
             pthread_mutex_unlock(&gInitMutex);
-            return;
+            return false;
         }
     }
     gThreadTLSKeyCount++;
@@ -622,7 +658,7 @@
     status = pthread_attr_init(&threadAttr);
     if (status) {
         LOGE("Failed to init thread attribute.");
-        return;
+        return false;
     }
 
     mWndSurface = NULL;
@@ -642,12 +678,16 @@
     status = pthread_create(&mThreadId, &threadAttr, threadProc, this);
     if (status) {
         LOGE("Failed to start rs context thread.");
-        return;
+        return false;
     }
-    while(!mRunning) {
+    while(!mRunning && (mError == RS_ERROR_NONE)) {
         usleep(100);
     }
 
+    if (mError != RS_ERROR_NONE) {
+        return false;
+    }
+
     mWorkers.mCompleteSignal.init();
     mWorkers.mRunningCount = 0;
     mWorkers.mLaunchCount = 0;
@@ -660,6 +700,7 @@
         }
     }
     pthread_attr_destroy(&threadAttr);
+    return true;
 }
 
 Context::~Context()
@@ -1020,7 +1061,7 @@
 {
     LOGV("rsContextCreate %p", vdev);
     Device * dev = static_cast<Device *>(vdev);
-    Context *rsc = new Context(dev, NULL);
+    Context *rsc = Context::createContext(dev, NULL);
     return rsc;
 }
 
@@ -1028,7 +1069,7 @@
 {
     LOGV("rsContextCreateGL %p", vdev);
     Device * dev = static_cast<Device *>(vdev);
-    Context *rsc = new Context(dev, &sc);
+    Context *rsc = Context::createContext(dev, &sc);
     LOGV("rsContextCreateGL ret %p ", rsc);
     return rsc;
 }
diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h
index e269d4e..2017ceb7 100644
--- a/libs/rs/rsContext.h
+++ b/libs/rs/rsContext.h
@@ -69,7 +69,7 @@
 class Context
 {
 public:
-    Context(Device *, const RsSurfaceConfig *sc);
+    static Context * createContext(Device *, const RsSurfaceConfig *sc);
     ~Context();
 
     static pthread_key_t gThreadTLSKey;
@@ -276,9 +276,10 @@
 
 private:
     Context();
+    bool initContext(Device *, const RsSurfaceConfig *sc);
 
-    void initEGL();
-    void initGLThread();
+
+    bool initGLThread();
     void deinitEGL();
 
     uint32_t runRootScript();