goldfish-opengl: Protect shared texture objects map
This fixes a crash in libOpenglCodecCommon by protecting
the shared texture objects map with a ReadWriteLock.
BUG=213574323
TEST=dEQP-EGL.functional.sharing.gles2.multithread.*
Change-Id: I61f9fe3c3892c3c482cee7893526f5de854b1c4d
diff --git a/shared/OpenglCodecCommon/GLClientState.cpp b/shared/OpenglCodecCommon/GLClientState.cpp
index 74b600c..fc6f130 100644
--- a/shared/OpenglCodecCommon/GLClientState.cpp
+++ b/shared/OpenglCodecCommon/GLClientState.cpp
@@ -36,6 +36,9 @@
#include <GLES3/gl3.h>
#include <GLES3/gl31.h>
+using android::base::guest::AutoReadLock;
+using android::base::guest::AutoWriteLock;
+
void GLClientState::init() {
m_initialized = false;
@@ -1521,19 +1524,25 @@
tex->hasCubeNegZ = false;
tex->hasCubePosZ = false;
- (*(m_tex.textureRecs))[id] = tex;
+ AutoWriteLock guard(m_tex.textureRecs->lock);
+ m_tex.textureRecs->map[id] = tex;
return tex;
}
-TextureRec* GLClientState::getTextureRec(GLuint id) const {
+TextureRec* GLClientState::getTextureRecLocked(GLuint id) const {
SharedTextureDataMap::const_iterator it =
- m_tex.textureRecs->find(id);
- if (it == m_tex.textureRecs->end()) {
+ m_tex.textureRecs->map.find(id);
+ if (it == m_tex.textureRecs->map.end()) {
return NULL;
}
return it->second;
}
+TextureRec* GLClientState::getTextureRec(GLuint id) const {
+ AutoReadLock guard(m_tex.textureRecs->lock);
+ return getTextureRecLocked(id);
+}
+
void GLClientState::setBoundTextureInternalFormat(GLenum target, GLint internalformat) {
GLuint texture = getBoundTexture(target);
TextureRec* texrec = getTextureRec(texture);
@@ -2042,12 +2051,13 @@
// - could swap deleted textures to the end and re-sort.
TextureRec* texrec;
for (const GLuint* texture = textures; texture != textures + n; texture++) {
- texrec = getTextureRec(*texture);
+ AutoWriteLock guard(m_tex.textureRecs->lock);
+ texrec = getTextureRecLocked(*texture);
if (texrec && texrec->dims) {
delete [] texrec->dims;
}
if (texrec) {
- m_tex.textureRecs->erase(*texture);
+ m_tex.textureRecs->map.erase(*texture);
delete texrec;
for (TextureUnit* unit = m_tex.unit;
unit != m_tex.unit + MAX_TEXTURE_UNITS;
diff --git a/shared/OpenglCodecCommon/GLClientState.h b/shared/OpenglCodecCommon/GLClientState.h
index ff20287..bc65aa7 100644
--- a/shared/OpenglCodecCommon/GLClientState.h
+++ b/shared/OpenglCodecCommon/GLClientState.h
@@ -745,6 +745,7 @@
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;
public:
bool isTexture(GLuint name) const;
diff --git a/shared/OpenglCodecCommon/TextureSharedData.h b/shared/OpenglCodecCommon/TextureSharedData.h
index 96827ef..aee1996 100644
--- a/shared/OpenglCodecCommon/TextureSharedData.h
+++ b/shared/OpenglCodecCommon/TextureSharedData.h
@@ -19,6 +19,10 @@
#include <GLES/gl.h>
#include <map>
+#include "android/base/synchronization/AndroidLock.h"
+
+using android::base::guest::ReadWriteLock;
+
struct TextureDims {
std::map<GLsizei, GLsizei> widths;
std::map<GLsizei, GLsizei> heights;
@@ -44,6 +48,14 @@
bool hasCubePosZ;
};
-typedef std::map<GLuint, TextureRec*> SharedTextureDataMap;
+struct SharedTextureDataMap {
+ using MapType = std::map<GLuint, TextureRec*>;
+
+ using iterator = MapType::iterator;
+ using const_iterator = MapType::const_iterator;
+
+ MapType map;
+ ReadWriteLock lock;
+};
#endif