EmuGL: refinements to GLESv1 image_external

* EGLImageTargetRenderbufferStorageOES was incorrectly accepting
  TEXTURE_EXTERNAL_OES as a target. Revert that; the host GL will
  correctly reject it with INVALID_ENUM.

* Handle the REQUIRED_TEXTURE_IMAGE_UNITS_OES texparameter query.

* Validate texture parameters set on TEXTURE_EXTERNAL textures;
  otherwise invalid parameters would work on the emulator but not on a
  real device.

Change-Id: I49a088608d58a9822f33e5916bd354eee3709127
diff --git a/tools/emulator/opengl/system/GLESv1/gl.cpp b/tools/emulator/opengl/system/GLESv1/gl.cpp
index 07afade..43577e0 100644
--- a/tools/emulator/opengl/system/GLESv1/gl.cpp
+++ b/tools/emulator/opengl/system/GLESv1/gl.cpp
@@ -73,13 +73,9 @@
         return;
     }
 
-    GET_CONTEXT;
     DEFINE_AND_VALIDATE_HOST_CONNECTION();
-
-    ctx->override2DTextureTarget(target);
     rcEnc->rcBindRenderbuffer(rcEnc,
             ((cb_handle_t *)(native_buffer->handle))->hostHandle);
-    ctx->restore2DTextureTarget();
 
     return;
 }
diff --git a/tools/emulator/opengl/system/GLESv1_enc/GLEncoder.cpp b/tools/emulator/opengl/system/GLESv1_enc/GLEncoder.cpp
index dc7c527..4a36537 100644
--- a/tools/emulator/opengl/system/GLESv1_enc/GLEncoder.cpp
+++ b/tools/emulator/opengl/system/GLESv1_enc/GLEncoder.cpp
@@ -634,6 +634,7 @@
     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);
@@ -735,12 +736,20 @@
     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_glGetTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params);
-        ctx->restore2DTextureTarget();
-    } else {
-        ctx->m_glGetTexParameteriv_enc(ctx, target, pname, params);
+    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;
     }
 }
 
@@ -759,12 +768,35 @@
     }
 }
 
+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);
@@ -780,6 +812,10 @@
     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);
@@ -795,6 +831,10 @@
     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);
@@ -810,6 +850,10 @@
     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);
@@ -825,6 +869,10 @@
     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);
@@ -840,6 +888,10 @@
     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);