Snap for 8708169 from ac9dace35eeb6d30afbfc0ea064aaf112e2d14da to mainline-go-adservices-release

Change-Id: I0eeba7a3ff4e29d61cc7a6dd35cfb6bcbee36e47
diff --git a/shared/OpenglCodecCommon/GLClientState.cpp b/shared/OpenglCodecCommon/GLClientState.cpp
index 2dfc80e..852f36a 100644
--- a/shared/OpenglCodecCommon/GLClientState.cpp
+++ b/shared/OpenglCodecCommon/GLClientState.cpp
@@ -1051,17 +1051,17 @@
 }
 
 bool GLClientState::isTexture(GLuint tex_name) const {
-    return getTextureRec(tex_name);
+    return getTextureRec(tex_name) != nullptr;
 }
 
 bool GLClientState::isTextureWithStorage(GLuint tex_name) const {
-    TextureRec* rec = getTextureRec(tex_name);
+    TextureRec* rec = getTextureRecPtr(tex_name);
     if (!rec) return false;
     return rec->hasStorage;
 }
 
 bool GLClientState::isTextureCubeMap(GLuint tex_name) const {
-    TextureRec* texrec = getTextureRec(tex_name);
+    TextureRec* texrec = getTextureRecPtr(tex_name);
     if (!texrec) return false;
     switch (texrec->target) {
         case GL_TEXTURE_CUBE_MAP:
@@ -1445,7 +1445,7 @@
 {
     GLboolean first = GL_FALSE;
 
-    TextureRec* texrec = getTextureRec(texture);
+    TextureRec* texrec = getTextureRecPtr(texture);
     if (!texrec) {
         texrec = addTextureRec(texture, target);
         first = GL_TRUE;
@@ -1496,7 +1496,7 @@
         setBoundRenderbufferDimensions(width, height);
     } else {
         GLuint texture = getBoundTexture(target);
-        TextureRec* texrec = getTextureRec(texture);
+        TextureRec* texrec = getTextureRecPtr(texture);
         if (!texrec) return;
         texrec->boundEGLImage = true;
         setBoundTextureInternalFormat(target, GL_RGBA);
@@ -1526,11 +1526,12 @@
     tex->hasCubePosZ = false;
 
     AutoWriteLock guard(m_tex.textureRecs->lock);
-    m_tex.textureRecs->map[id] = tex;
+    m_tex.textureRecs->map[id] = std::shared_ptr<TextureRec>(tex);
     return tex;
 }
 
-TextureRec* GLClientState::getTextureRecLocked(GLuint id) const {
+std::shared_ptr<TextureRec> GLClientState::getTextureRec(GLuint id) const {
+    AutoReadLock guard(m_tex.textureRecs->lock);
     SharedTextureDataMap::const_iterator it =
         m_tex.textureRecs->map.find(id);
     if (it == m_tex.textureRecs->map.end()) {
@@ -1539,28 +1540,37 @@
     return it->second;
 }
 
-TextureRec* GLClientState::getTextureRec(GLuint id) const {
+TextureRec* GLClientState::getTextureRecPtrLocked(GLuint id) const {
+    SharedTextureDataMap::const_iterator it =
+        m_tex.textureRecs->map.find(id);
+    if (it == m_tex.textureRecs->map.end()) {
+        return NULL;
+    }
+    return it->second.get();
+}
+
+TextureRec* GLClientState::getTextureRecPtr(GLuint id) const {
     AutoReadLock guard(m_tex.textureRecs->lock);
-    return getTextureRecLocked(id);
+    return getTextureRecPtrLocked(id);
 }
 
 void GLClientState::setBoundTextureInternalFormat(GLenum target, GLint internalformat) {
     GLuint texture = getBoundTexture(target);
-    TextureRec* texrec = getTextureRec(texture);
+    TextureRec* texrec = getTextureRecPtr(texture);
     if (!texrec) return;
     texrec->internalformat = internalformat;
 }
 
 void GLClientState::setBoundTextureFormat(GLenum target, GLenum format) {
     GLuint texture = getBoundTexture(target);
-    TextureRec* texrec = getTextureRec(texture);
+    TextureRec* texrec = getTextureRecPtr(texture);
     if (!texrec) return;
     texrec->format = format;
 }
 
 void GLClientState::setBoundTextureType(GLenum target, GLenum type) {
     GLuint texture = getBoundTexture(target);
-    TextureRec* texrec = getTextureRec(texture);
+    TextureRec* texrec = getTextureRecPtr(texture);
     if (!texrec) return;
     texrec->type = type;
 }
@@ -1585,7 +1595,7 @@
 
 void GLClientState::setBoundTextureDims(GLenum target, GLenum cubetarget, GLsizei level, GLsizei width, GLsizei height, GLsizei depth) {
     GLuint texture = getBoundTexture(target);
-    TextureRec* texrec = getTextureRec(texture);
+    TextureRec* texrec = getTextureRecPtr(texture);
     if (!texrec) {
         return;
     }
@@ -1643,7 +1653,7 @@
 
 void GLClientState::setBoundTextureSamples(GLenum target, GLsizei samples) {
     GLuint texture = getBoundTexture(target);
-    TextureRec* texrec = getTextureRec(texture);
+    TextureRec* texrec = getTextureRecPtr(texture);
     if (!texrec) return;
     texrec->multisamples = samples;
 }
@@ -1652,7 +1662,7 @@
     if (stateTarget != GL_TEXTURE_CUBE_MAP) return;
 
     GLuint texture = getBoundTexture(stateTarget);
-    TextureRec* texrec = getTextureRec(texture);
+    TextureRec* texrec = getTextureRecPtr(texture);
     if (!texrec) return;
 
     switch (cubeTarget) {
@@ -1679,7 +1689,7 @@
 
 void GLClientState::setBoundTextureImmutableFormat(GLenum target) {
     GLuint texture = getBoundTexture(target);
-    TextureRec* texrec = getTextureRec(texture);
+    TextureRec* texrec = getTextureRecPtr(texture);
     if (!texrec) return;
     texrec->immutable = true;
     if (target == GL_TEXTURE_CUBE_MAP) {
@@ -1694,14 +1704,14 @@
 
 bool GLClientState::isBoundTextureImmutableFormat(GLenum target) const {
     GLuint texture = getBoundTexture(target);
-    TextureRec* texrec = getTextureRec(texture);
+    TextureRec* texrec = getTextureRecPtr(texture);
     if (!texrec) return false;
     return texrec->immutable;
 }
 
 bool GLClientState::isBoundTextureComplete(GLenum target) const {
     GLuint texture = getBoundTexture(target);
-    TextureRec* texrec = getTextureRec(texture);
+    TextureRec* texrec = getTextureRecPtr(texture);
     if (!texrec) return false;
 
     if (texrec->immutable) return true;
@@ -1914,7 +1924,7 @@
     if (!renderable) return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
 
     // Check dimensions
-    GLuint id;
+    std::shared_ptr<TextureRec> texrec;
     std::shared_ptr<RboProps> rbo;
     switch (fbo_format_info.type) {
     case FBO_ATTACHMENT_RENDERBUFFER:
@@ -1927,13 +1937,14 @@
         }
         break;
     case FBO_ATTACHMENT_TEXTURE:
-        id = getFboAttachmentTextureId(target, attachment);
+        texrec = getFboAttachmentTexture(target, attachment);
         if (!fbo_format_info.tex_external) {
-            if (0 == queryTexWidth(fbo_format_info.tex_level, id) || 0 == queryTexHeight(fbo_format_info.tex_level, id)) {
+            if (0 == texrec->dims->widths[fbo_format_info.tex_level] ||
+                    0 == texrec->dims->heights[fbo_format_info.tex_level]) {
                 ALOGD("%s: texture has zero dimension\n", __func__);
                 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
             }
-            GLsizei depth = queryTexDepth(fbo_format_info.tex_level, id);
+            GLsizei depth = texrec->dims->depths[fbo_format_info.tex_level];
             if (fbo_format_info.tex_layer >= depth) {
                 ALOGD("%s: texture layer/zoffset too high, wanted %d but only have %d layers\n", __func__,
                       fbo_format_info.tex_layer, depth);
@@ -2054,13 +2065,12 @@
     TextureRec* texrec;
     for (const GLuint* texture = textures; texture != textures + n; texture++) {
         AutoWriteLock guard(m_tex.textureRecs->lock);
-        texrec = getTextureRecLocked(*texture);
+        texrec = getTextureRecPtrLocked(*texture);
         if (texrec && texrec->dims) {
             delete [] texrec->dims;
         }
         if (texrec) {
             m_tex.textureRecs->map.erase(*texture);
-            delete texrec;
             for (TextureUnit* unit = m_tex.unit;
                  unit != m_tex.unit + MAX_TEXTURE_UNITS;
                  unit++)
@@ -2158,13 +2168,13 @@
 // FBO//////////////////////////////////////////////////////////////////////////
 
 GLint GLClientState::queryTexInternalFormat(GLuint tex_name) const {
-    TextureRec* texrec = getTextureRec(tex_name);
+    TextureRec* texrec = getTextureRecPtr(tex_name);
     if (!texrec) return -1;
     return texrec->internalformat;
 }
 
 GLsizei GLClientState::queryTexWidth(GLsizei level, GLuint tex_name) const {
-    TextureRec* texrec = getTextureRec(tex_name);
+    TextureRec* texrec = getTextureRecPtr(tex_name);
     if (!texrec) {
         return 0;
     }
@@ -2172,43 +2182,43 @@
 }
 
 GLsizei GLClientState::queryTexHeight(GLsizei level, GLuint tex_name) const {
-    TextureRec* texrec = getTextureRec(tex_name);
+    TextureRec* texrec = getTextureRecPtr(tex_name);
     if (!texrec) return 0;
     return texrec->dims->heights[level];
 }
 
 GLsizei GLClientState::queryTexDepth(GLsizei level, GLuint tex_name) const {
-    TextureRec* texrec = getTextureRec(tex_name);
+    TextureRec* texrec = getTextureRecPtr(tex_name);
     if (!texrec) return 0;
     return texrec->dims->depths[level];
 }
 
 bool GLClientState::queryTexEGLImageBacked(GLuint tex_name) const {
-    TextureRec* texrec = getTextureRec(tex_name);
+    TextureRec* texrec = getTextureRecPtr(tex_name);
     if (!texrec) return false;
     return texrec->boundEGLImage;
 }
 
 GLenum GLClientState::queryTexFormat(GLuint tex_name) const {
-    TextureRec* texrec = getTextureRec(tex_name);
+    TextureRec* texrec = getTextureRecPtr(tex_name);
     if (!texrec) return -1;
     return texrec->format;
 }
 
 GLenum GLClientState::queryTexType(GLuint tex_name) const {
-    TextureRec* texrec = getTextureRec(tex_name);
+    TextureRec* texrec = getTextureRecPtr(tex_name);
     if (!texrec) return -1;
     return texrec->type;
 }
 
 GLsizei GLClientState::queryTexSamples(GLuint tex_name) const {
-    TextureRec* texrec = getTextureRec(tex_name);
+    TextureRec* texrec = getTextureRecPtr(tex_name);
     if (!texrec) return 0;
     return texrec->multisamples;
 }
 
 GLenum GLClientState::queryTexLastBoundTarget(GLuint tex_name) const {
-    TextureRec* texrec = getTextureRec(tex_name);
+    TextureRec* texrec = getTextureRecPtr(tex_name);
     if (!texrec) return GL_NONE;
     return texrec->target;
 }
@@ -2241,18 +2251,16 @@
                     props.colorAttachmenti_rbos[colorAttachmentIndex]->boundEGLImage;
         } else if (props.colorAttachmenti_hasTex[colorAttachmentIndex]) {
             res_info->type = FBO_ATTACHMENT_TEXTURE;
-            res_info->tex_external = queryTexEGLImageBacked(
-                    props.colorAttachmenti_textures[colorAttachmentIndex]);
+            res_info->tex_external =
+                    props.colorAttachmenti_textures[colorAttachmentIndex]->boundEGLImage;
             res_info->tex_internalformat =
-                queryTexInternalFormat(
-                        props.colorAttachmenti_textures[colorAttachmentIndex]);
+                    props.colorAttachmenti_textures[colorAttachmentIndex]->internalformat;
             res_info->tex_format =
-                queryTexFormat(
-                        props.colorAttachmenti_textures[colorAttachmentIndex]);
+                    props.colorAttachmenti_textures[colorAttachmentIndex]->format;
             res_info->tex_type =
-                queryTexType(props.colorAttachmenti_textures[colorAttachmentIndex]);
+                    props.colorAttachmenti_textures[colorAttachmentIndex]->type;
             res_info->tex_multisamples =
-                queryTexSamples(props.colorAttachmenti_textures[colorAttachmentIndex]);
+                    props.colorAttachmenti_textures[colorAttachmentIndex]->multisamples;
             res_info->tex_level = props.colorAttachmenti_texture_levels[colorAttachmentIndex];
             res_info->tex_layer = props.colorAttachmenti_texture_layers[colorAttachmentIndex];
         } else {
@@ -2269,12 +2277,11 @@
             res_info->rb_external = props.depthAttachment_rbo->boundEGLImage;
         } else if (props.depthAttachment_hasTexObj) {
             res_info->type = FBO_ATTACHMENT_TEXTURE;
-            res_info->tex_external = queryTexEGLImageBacked(props.depthAttachment_texture);
-            res_info->tex_internalformat = queryTexInternalFormat(props.depthAttachment_texture);
-            res_info->tex_format = queryTexFormat(props.depthAttachment_texture);
-            res_info->tex_type = queryTexType(props.depthAttachment_texture);
-            res_info->tex_multisamples =
-                queryTexSamples(props.depthAttachment_texture);
+            res_info->tex_external = props.depthAttachment_texture->boundEGLImage;
+            res_info->tex_internalformat = props.depthAttachment_texture->internalformat;
+            res_info->tex_format = props.depthAttachment_texture->format;
+            res_info->tex_type = props.depthAttachment_texture->type;
+            res_info->tex_multisamples = props.depthAttachment_texture->multisamples;
             res_info->tex_level = props.depthAttachment_texture_level;
             res_info->tex_layer = props.depthAttachment_texture_layer;
         } else {
@@ -2289,12 +2296,11 @@
             res_info->rb_external = props.stencilAttachment_rbo->boundEGLImage;
         } else if (props.stencilAttachment_hasTexObj) {
             res_info->type = FBO_ATTACHMENT_TEXTURE;
-            res_info->tex_external = queryTexEGLImageBacked(props.stencilAttachment_texture);
-            res_info->tex_internalformat = queryTexInternalFormat(props.stencilAttachment_texture);
-            res_info->tex_format = queryTexFormat(props.stencilAttachment_texture);
-            res_info->tex_type = queryTexType(props.stencilAttachment_texture);
-            res_info->tex_multisamples =
-                queryTexSamples(props.stencilAttachment_texture);
+            res_info->tex_external = props.stencilAttachment_texture->boundEGLImage;
+            res_info->tex_internalformat = props.stencilAttachment_texture->internalformat;
+            res_info->tex_format = props.stencilAttachment_texture->format;
+            res_info->tex_type = props.stencilAttachment_texture->type;
+            res_info->tex_multisamples = props.stencilAttachment_texture->multisamples;
             res_info->tex_level = props.depthAttachment_texture_level;
             res_info->tex_layer = props.depthAttachment_texture_layer;
         } else {
@@ -2309,12 +2315,11 @@
             res_info->rb_external = props.depthstencilAttachment_rbo->boundEGLImage;
         } else if (props.depthstencilAttachment_hasTexObj) {
             res_info->type = FBO_ATTACHMENT_TEXTURE;
-            res_info->tex_external = queryTexEGLImageBacked(props.depthstencilAttachment_texture);
-            res_info->tex_internalformat = queryTexInternalFormat(props.depthstencilAttachment_texture);
-            res_info->tex_format = queryTexFormat(props.depthstencilAttachment_texture);
-            res_info->tex_type = queryTexType(props.depthstencilAttachment_texture);
-            res_info->tex_multisamples =
-                queryTexSamples(props.depthstencilAttachment_texture);
+            res_info->tex_external = props.depthstencilAttachment_texture->boundEGLImage;
+            res_info->tex_internalformat = props.depthstencilAttachment_texture->internalformat;
+            res_info->tex_format = props.depthstencilAttachment_texture->format;
+            res_info->tex_type = props.depthstencilAttachment_texture->type;
+            res_info->tex_multisamples = props.depthstencilAttachment_texture->multisamples;
             res_info->tex_level = props.depthAttachment_texture_level;
             res_info->tex_layer = props.depthAttachment_texture_layer;
         } else {
@@ -2538,6 +2543,7 @@
         GLenum attachment, GLuint texture, GLint level, GLint layer) {
 
     bool attach = texture != 0;
+    std::shared_ptr<TextureRec> texrec = getTextureRec(texture);
 
     int colorAttachmentIndex =
         glUtilsColorAttachmentIndex(attachment);
@@ -2545,7 +2551,7 @@
     boundFboProps(target).completenessDirty = true;
 
     if (colorAttachmentIndex != -1) {
-        boundFboProps(target).colorAttachmenti_textures[colorAttachmentIndex] = texture;
+        boundFboProps(target).colorAttachmenti_textures[colorAttachmentIndex] = texrec;
         boundFboProps(target).colorAttachmenti_texture_levels[colorAttachmentIndex] = level;
         boundFboProps(target).colorAttachmenti_texture_layers[colorAttachmentIndex] = layer;
         boundFboProps(target).colorAttachmenti_hasTex[colorAttachmentIndex] = attach;
@@ -2553,23 +2559,23 @@
 
     switch (attachment) {
     case GL_DEPTH_ATTACHMENT:
-        boundFboProps(target).depthAttachment_texture = texture;
+        boundFboProps(target).depthAttachment_texture = texrec;
         boundFboProps(target).depthAttachment_texture_level = level;
         boundFboProps(target).depthAttachment_texture_layer = layer;
         boundFboProps(target).depthAttachment_hasTexObj = attach;
         break;
     case GL_STENCIL_ATTACHMENT:
-        boundFboProps(target).stencilAttachment_texture = texture;
+        boundFboProps(target).stencilAttachment_texture = texrec;
         boundFboProps(target).stencilAttachment_texture_level = level;
         boundFboProps(target).stencilAttachment_texture_layer = layer;
         boundFboProps(target).stencilAttachment_hasTexObj = attach;
         break;
     case GL_DEPTH_STENCIL_ATTACHMENT:
-        boundFboProps(target).depthstencilAttachment_texture = texture;
+        boundFboProps(target).depthstencilAttachment_texture = texrec;
         boundFboProps(target).depthstencilAttachment_hasTexObj = attach;
-        boundFboProps(target).stencilAttachment_texture = texture;
+        boundFboProps(target).stencilAttachment_texture = texrec;
         boundFboProps(target).stencilAttachment_hasTexObj = attach;
-        boundFboProps(target).depthAttachment_texture = texture;
+        boundFboProps(target).depthAttachment_texture = texrec;
         boundFboProps(target).depthAttachment_hasTexObj = attach;
         boundFboProps(target).depthAttachment_texture_level = level;
         boundFboProps(target).depthAttachment_texture_layer = layer;
@@ -2579,8 +2585,8 @@
     }
 }
 
-GLuint GLClientState::getFboAttachmentTextureId(GLenum target, GLenum attachment) const {
-    GLuint res = 0; // conservative
+std::shared_ptr<TextureRec> GLClientState::getFboAttachmentTexture(GLenum target, GLenum attachment) const {
+    std::shared_ptr<TextureRec> res = {}; // conservative
 
     int colorAttachmentIndex =
         glUtilsColorAttachmentIndex(attachment);
@@ -2731,12 +2737,13 @@
 }
 
 void GLClientState::setFboCompletenessDirtyForTexture(GLuint texture) {
+    std::shared_ptr<TextureRec> texrec = getTextureRec(texture);
     std::map<GLuint, FboProps>::iterator it = mFboState.fboData.begin();
     while (it != mFboState.fboData.end()) {
         FboProps& props = it->second;
         for (int i = 0; i < m_hostDriverCaps.max_color_attachments; ++i) {
             if (props.colorAttachmenti_hasTex[i]) {
-                if (texture == props.colorAttachmenti_textures[i]) {
+                if (texrec == props.colorAttachmenti_textures[i]) {
                     props.completenessDirty = true;
                     return;
                 }
@@ -2744,21 +2751,21 @@
         }
 
         if (props.depthAttachment_hasTexObj) {
-            if (texture == props.depthAttachment_texture) {
+            if (texrec == props.depthAttachment_texture) {
                     props.completenessDirty = true;
                     return;
             }
         }
 
         if (props.stencilAttachment_hasTexObj) {
-            if (texture == props.stencilAttachment_texture) {
+            if (texrec == props.stencilAttachment_texture) {
                 props.completenessDirty = true;
                 return;
             }
         }
 
         if (props.depthstencilAttachment_hasTexObj) {
-            if (texture == props.depthstencilAttachment_texture) {
+            if (texrec == props.depthstencilAttachment_texture) {
                 props.completenessDirty = true;
                 return;
             }
@@ -2832,51 +2839,21 @@
     return res;
 }
 
-GLuint GLClientState::objectOfAttachment(GLenum target, GLenum attachment) const {
+bool GLClientState::depthStencilHasSameObject(GLenum target) const {
     const FboProps& props = boundFboProps_const(target);
 
-    int colorAttachmentIndex =
-        glUtilsColorAttachmentIndex(attachment);
-
-    if (colorAttachmentIndex != -1) {
-        if (props.colorAttachmenti_hasTex[colorAttachmentIndex]) {
-            return props.colorAttachmenti_textures[colorAttachmentIndex];
-        } else if (props.colorAttachmenti_hasRbo[colorAttachmentIndex]) {
-            return props.colorAttachmenti_rbos[colorAttachmentIndex]->id;
-        } else {
-            return 0;
-        }
+    if (props.depthAttachment_hasTexObj != props.stencilAttachment_hasTexObj
+            || props.depthAttachment_hasRbo != props.stencilAttachment_hasRbo) {
+        return false;
     }
-
-    switch (attachment) {
-    case GL_DEPTH_ATTACHMENT:
-        if (props.depthAttachment_hasTexObj) {
-            return props.depthAttachment_texture;
-        } else if (props.depthAttachment_hasRbo) {
-            return props.depthAttachment_rbo->id;
-        } else {
-            return 0;
-        }
-        break;
-    case GL_STENCIL_ATTACHMENT:
-        if (props.stencilAttachment_hasTexObj) {
-            return props.stencilAttachment_texture;
-        } else if (props.stencilAttachment_hasRbo) {
-            return props.stencilAttachment_rbo->id;
-        } else {
-            return 0;
-        }
-    case GL_DEPTH_STENCIL_ATTACHMENT:
-        if (props.depthstencilAttachment_hasTexObj) {
-            return props.depthstencilAttachment_texture;
-        } else if (props.depthstencilAttachment_hasRbo) {
-            return props.depthstencilAttachment_rbo->id;
-        } else {
-            return 0;
-        }
-        break;
+    if (props.depthAttachment_hasTexObj) {
+        return props.depthAttachment_texture == props.stencilAttachment_texture;
     }
-    return 0;
+    if (props.depthAttachment_hasRbo) {
+        return props.depthAttachment_rbo == props.stencilAttachment_rbo;
+    }
+    // No attachment in either
+    return true;
 }
 
 void GLClientState::setTransformFeedbackActive(bool active) {
diff --git a/shared/OpenglCodecCommon/GLClientState.h b/shared/OpenglCodecCommon/GLClientState.h
index b71054f..0639962 100644
--- a/shared/OpenglCodecCommon/GLClientState.h
+++ b/shared/OpenglCodecCommon/GLClientState.h
@@ -40,6 +40,7 @@
 
 #include <vector>
 #include <map>
+#include <memory>
 #include <set>
 #include <string>
 
@@ -81,7 +82,7 @@
     bool previouslyBound;
     bool completenessDirty;
     GLenum cachedCompleteness;
-    std::vector<GLuint> colorAttachmenti_textures;
+    std::vector<std::shared_ptr<TextureRec>> colorAttachmenti_textures;
     std::vector<GLint> colorAttachmenti_texture_levels;
     std::vector<GLint> colorAttachmenti_texture_layers;
 
@@ -90,9 +91,9 @@
     GLint stencilAttachment_texture_level;
     GLint stencilAttachment_texture_layer;
 
-    GLuint depthAttachment_texture;
-    GLuint stencilAttachment_texture;
-    GLuint depthstencilAttachment_texture;
+    std::shared_ptr<TextureRec> depthAttachment_texture;
+    std::shared_ptr<TextureRec> stencilAttachment_texture;
+    std::shared_ptr<TextureRec> depthstencilAttachment_texture;
 
     std::vector<bool> colorAttachmenti_hasTex;
     bool depthAttachment_hasTexObj;
@@ -489,7 +490,7 @@
 
     // Texture object -> FBO
     void attachTextureObject(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
-    GLuint getFboAttachmentTextureId(GLenum target, GLenum attachment) const;
+    std::shared_ptr<TextureRec> getFboAttachmentTexture(GLenum target, GLenum attachment) const;
 
     // RBO -> FBO
     void detachRbo(GLuint renderbuffer);
@@ -499,7 +500,7 @@
 
     // FBO attachments in general
     bool attachmentHasObject(GLenum target, GLenum attachment) const;
-    GLuint objectOfAttachment(GLenum target, GLenum attachment) const;
+    bool depthStencilHasSameObject(GLenum target) const;
 
     // Dirty FBO completeness
     void setFboCompletenessDirtyForTexture(GLuint texture);
@@ -739,8 +740,9 @@
 
     static int compareTexId(const void* pid, const void* prec);
     TextureRec* addTextureRec(GLuint id, GLenum target);
-    TextureRec* getTextureRec(GLuint id) const;
-    TextureRec* getTextureRecLocked(GLuint id) const;
+    std::shared_ptr<TextureRec> getTextureRec(GLuint id) const;
+    TextureRec* getTextureRecPtr(GLuint id) const;
+    TextureRec* getTextureRecPtrLocked(GLuint id) const;
 
 public:
     bool isTexture(GLuint name) const;
diff --git a/shared/OpenglCodecCommon/TextureSharedData.h b/shared/OpenglCodecCommon/TextureSharedData.h
index aee1996..fafb435 100644
--- a/shared/OpenglCodecCommon/TextureSharedData.h
+++ b/shared/OpenglCodecCommon/TextureSharedData.h
@@ -18,6 +18,7 @@
 
 #include <GLES/gl.h>
 #include <map>
+#include <memory>
 
 #include "android/base/synchronization/AndroidLock.h"
 
@@ -49,7 +50,7 @@
 };
 
 struct SharedTextureDataMap {
-  using MapType = std::map<GLuint, TextureRec*>;
+  using MapType = std::map<GLuint, std::shared_ptr<TextureRec>>;
 
   using iterator = MapType::iterator;
   using const_iterator = MapType::const_iterator;
diff --git a/system/GLESv2_enc/GL2Encoder.cpp b/system/GLESv2_enc/GL2Encoder.cpp
index 382274c..63b4ff4 100755
--- a/system/GLESv2_enc/GL2Encoder.cpp
+++ b/system/GLESv2_enc/GL2Encoder.cpp
@@ -3091,8 +3091,7 @@
         GL_INVALID_ENUM);
     SET_ERROR_IF(attachment == GL_DEPTH_STENCIL_ATTACHMENT &&
                  pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME &&
-                 (state->objectOfAttachment(target, GL_DEPTH_ATTACHMENT) !=
-                  state->objectOfAttachment(target, GL_STENCIL_ATTACHMENT)),
+                 !state->depthStencilHasSameObject(target),
                  GL_INVALID_OPERATION);
     SET_ERROR_IF(state->boundFramebuffer(target) &&
                  (attachment == GL_BACK ||