aboutsummaryrefslogtreecommitdiff
path: root/shared/OpenglCodecCommon
diff options
context:
space:
mode:
authorLingfeng Yang <lfy@google.com>2017-01-10 14:54:38 -0800
committerLingfeng Yang <lfy@google.com>2017-01-10 22:06:09 -0800
commit74e29295ec43efde4365f08f20d7e1515c182b99 (patch)
treedfc6c420d7d76b6799e154e3272f936e2f12c5ff /shared/OpenglCodecCommon
parente6556dcf96ef0b859fe04d8caf7c40fdd6d8d254 (diff)
downloadgoldfish-opengl-74e29295ec43efde4365f08f20d7e1515c182b99.tar.gz
[GLESv3] Texture state tracking upgrades
- TextureUtils to get the low down on all offset/size related calculations (ripped from SwiftShader) - This involves track of all PBO fields - Move TextureRec and friends to GLSharedGroup - Implement new encoder utils to use in encoder Change-Id: Ic6585f49d2928fe965181ec706d5fefa8713e0eb
Diffstat (limited to 'shared/OpenglCodecCommon')
-rw-r--r--shared/OpenglCodecCommon/Android.mk1
-rw-r--r--shared/OpenglCodecCommon/GLClientState.cpp402
-rw-r--r--shared/OpenglCodecCommon/GLClientState.h59
-rw-r--r--shared/OpenglCodecCommon/GLESTextureUtils.cpp287
-rw-r--r--shared/OpenglCodecCommon/GLESTextureUtils.h42
-rwxr-xr-xshared/OpenglCodecCommon/GLSharedGroup.cpp4
-rwxr-xr-xshared/OpenglCodecCommon/GLSharedGroup.h5
-rw-r--r--shared/OpenglCodecCommon/TextureSharedData.h42
8 files changed, 722 insertions, 120 deletions
diff --git a/shared/OpenglCodecCommon/Android.mk b/shared/OpenglCodecCommon/Android.mk
index e6aee8ab..b9cf6e55 100644
--- a/shared/OpenglCodecCommon/Android.mk
+++ b/shared/OpenglCodecCommon/Android.mk
@@ -5,6 +5,7 @@ LOCAL_PATH := $(call my-dir)
commonSources := \
GLClientState.cpp \
+ GLESTextureUtils.cpp \
ChecksumCalculator.cpp \
GLSharedGroup.cpp \
glUtils.cpp \
diff --git a/shared/OpenglCodecCommon/GLClientState.cpp b/shared/OpenglCodecCommon/GLClientState.cpp
index ac97fcf7..a4d81ea9 100644
--- a/shared/OpenglCodecCommon/GLClientState.cpp
+++ b/shared/OpenglCodecCommon/GLClientState.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
#include "GLClientState.h"
+#include "GLESTextureUtils.h"
#include "ErrorLog.h"
#include <stdio.h>
#include <stdlib.h>
@@ -25,6 +26,9 @@
#define MAX(a, b) ((a) < (b) ? (b) : (a))
#endif
+// Don't include these in the .h file, or we get weird compile errors.
+#include <GLES3/gl3.h>
+#include <GLES3/gl31.h>
GLClientState::GLClientState(int nLocations)
{
if (nLocations < LAST_LOCATION) {
@@ -60,11 +64,19 @@ GLClientState::GLClientState(int nLocations)
m_pixelStore.unpack_alignment = 4;
m_pixelStore.pack_alignment = 4;
+ m_pixelStore.unpack_row_length = 0;
+ m_pixelStore.unpack_image_height = 0;
+ m_pixelStore.unpack_skip_pixels = 0;
+ m_pixelStore.unpack_skip_rows = 0;
+ m_pixelStore.unpack_skip_images = 0;
+
+ m_pixelStore.pack_row_length = 0;
+ m_pixelStore.pack_skip_pixels = 0;
+ m_pixelStore.pack_skip_rows = 0;
+
memset(m_tex.unit, 0, sizeof(m_tex.unit));
m_tex.activeUnit = &m_tex.unit[0];
- m_tex.textures = NULL;
- m_tex.numTextures = 0;
- m_tex.allocTextures = 0;
+ m_tex.textureRecs = NULL;
mRboState.boundRenderbuffer = 0;
mRboState.boundRenderbufferIndex = 0;
@@ -212,46 +224,138 @@ int GLClientState::setPixelStore(GLenum param, GLint value)
int retval = 0;
switch(param) {
case GL_UNPACK_ALIGNMENT:
- if (value == 1 || value == 2 || value == 4 || value == 8) {
- m_pixelStore.unpack_alignment = value;
- } else {
- retval = GL_INVALID_VALUE;
- }
+ m_pixelStore.unpack_alignment = value;
break;
case GL_PACK_ALIGNMENT:
- if (value == 1 || value == 2 || value == 4 || value == 8) {
- m_pixelStore.pack_alignment = value;
- } else {
- retval = GL_INVALID_VALUE;
- }
+ m_pixelStore.pack_alignment = value;
+ break;
+ case GL_UNPACK_ROW_LENGTH:
+ m_pixelStore.unpack_row_length = value;
+ break;
+ case GL_UNPACK_IMAGE_HEIGHT:
+ m_pixelStore.unpack_image_height = value;
+ break;
+ case GL_UNPACK_SKIP_PIXELS:
+ m_pixelStore.unpack_skip_pixels = value;
+ break;
+ case GL_UNPACK_SKIP_ROWS:
+ m_pixelStore.unpack_skip_rows = value;
+ break;
+ case GL_UNPACK_SKIP_IMAGES:
+ m_pixelStore.unpack_skip_images = value;
+ break;
+ case GL_PACK_ROW_LENGTH:
+ m_pixelStore.pack_row_length = value;
+ break;
+ case GL_PACK_SKIP_PIXELS:
+ m_pixelStore.pack_skip_pixels = value;
break;
- default:
- retval = GL_INVALID_ENUM;
+ case GL_PACK_SKIP_ROWS:
+ m_pixelStore.pack_skip_rows = value;
+ break;
+ default:
+ retval = GL_INVALID_ENUM;
}
return retval;
}
+size_t GLClientState::pixelDataSize(GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, int pack) const
+{
+ if (width <= 0 || height <= 0 || depth <= 0) return 0;
+
+ ALOGV("%s: pack? %d", __FUNCTION__, pack);
+ if (pack) {
+ ALOGV("%s: pack stats", __FUNCTION__);
+ ALOGV("%s: pack align %d", __FUNCTION__, m_pixelStore.pack_alignment);
+ ALOGV("%s: pack rowlen %d", __FUNCTION__, m_pixelStore.pack_row_length);
+ ALOGV("%s: pack skippixels %d", __FUNCTION__, m_pixelStore.pack_skip_pixels);
+ ALOGV("%s: pack skiprows %d", __FUNCTION__, m_pixelStore.pack_skip_rows);
+ } else {
+ ALOGV("%s: unpack stats", __FUNCTION__);
+ ALOGV("%s: unpack align %d", __FUNCTION__, m_pixelStore.unpack_alignment);
+ ALOGV("%s: unpack rowlen %d", __FUNCTION__, m_pixelStore.unpack_row_length);
+ ALOGV("%s: unpack imgheight %d", __FUNCTION__, m_pixelStore.unpack_image_height);
+ ALOGV("%s: unpack skippixels %d", __FUNCTION__, m_pixelStore.unpack_skip_pixels);
+ ALOGV("%s: unpack skiprows %d", __FUNCTION__, m_pixelStore.unpack_skip_rows);
+ ALOGV("%s: unpack skipimages %d", __FUNCTION__, m_pixelStore.unpack_skip_images);
+ }
+ return GLESTextureUtils::computeTotalImageSize(
+ width, height, depth,
+ format, type,
+ pack ? m_pixelStore.pack_alignment : m_pixelStore.unpack_alignment,
+ pack ? m_pixelStore.pack_row_length : m_pixelStore.unpack_row_length,
+ pack ? 0 : m_pixelStore.unpack_image_height,
+ pack ? m_pixelStore.pack_skip_pixels : m_pixelStore.unpack_skip_pixels,
+ pack ? m_pixelStore.pack_skip_rows : m_pixelStore.unpack_skip_rows,
+ pack ? 0 : m_pixelStore.unpack_skip_images);
+}
+
+size_t GLClientState::pboNeededDataSize(GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, int pack) const
+{
+ if (width <= 0 || height <= 0 || depth <= 0) return 0;
+
+ ALOGV("%s: pack? %d", __FUNCTION__, pack);
+ if (pack) {
+ ALOGV("%s: pack stats", __FUNCTION__);
+ ALOGV("%s: pack align %d", __FUNCTION__, m_pixelStore.pack_alignment);
+ ALOGV("%s: pack rowlen %d", __FUNCTION__, m_pixelStore.pack_row_length);
+ ALOGV("%s: pack skippixels %d", __FUNCTION__, m_pixelStore.pack_skip_pixels);
+ ALOGV("%s: pack skiprows %d", __FUNCTION__, m_pixelStore.pack_skip_rows);
+ } else {
+ ALOGV("%s: unpack stats", __FUNCTION__);
+ ALOGV("%s: unpack align %d", __FUNCTION__, m_pixelStore.unpack_alignment);
+ ALOGV("%s: unpack rowlen %d", __FUNCTION__, m_pixelStore.unpack_row_length);
+ ALOGV("%s: unpack imgheight %d", __FUNCTION__, m_pixelStore.unpack_image_height);
+ ALOGV("%s: unpack skippixels %d", __FUNCTION__, m_pixelStore.unpack_skip_pixels);
+ ALOGV("%s: unpack skiprows %d", __FUNCTION__, m_pixelStore.unpack_skip_rows);
+ ALOGV("%s: unpack skipimages %d", __FUNCTION__, m_pixelStore.unpack_skip_images);
+ }
+ return GLESTextureUtils::computeNeededBufferSize(
+ width, height, depth,
+ format, type,
+ pack ? m_pixelStore.pack_alignment : m_pixelStore.unpack_alignment,
+ pack ? m_pixelStore.pack_row_length : m_pixelStore.unpack_row_length,
+ pack ? 0 : m_pixelStore.unpack_image_height,
+ pack ? m_pixelStore.pack_skip_pixels : m_pixelStore.unpack_skip_pixels,
+ pack ? m_pixelStore.pack_skip_rows : m_pixelStore.unpack_skip_rows,
+ pack ? 0 : m_pixelStore.unpack_skip_images);
+}
-size_t GLClientState::pixelDataSize(GLsizei width, GLsizei height, GLenum format, GLenum type, int pack) const
+size_t GLClientState::clearBufferNumElts(GLenum buffer) const
{
- if (width <= 0 || height <= 0) return 0;
+ switch (buffer) {
+ case GL_COLOR:
+ return 4;
+ case GL_DEPTH:
+ case GL_STENCIL:
+ return 1;
+ }
+ return 1;
+}
- int pixelsize = glUtilsPixelBitSize(format, type) >> 3;
+void GLClientState::setNumActiveUniformsInUniformBlock(GLuint program, GLuint uniformBlockIndex, GLint numActiveUniforms) {
+ UniformBlockInfoKey key;
+ key.program = program;
+ key.uniformBlockIndex = uniformBlockIndex;
- int alignment = pack ? m_pixelStore.pack_alignment : m_pixelStore.unpack_alignment;
+ UniformBlockUniformInfo info;
+ info.numActiveUniforms = (size_t)numActiveUniforms;
+
+ m_uniformBlockInfoMap[key] = info;
+}
+
+size_t GLClientState::numActiveUniformsInUniformBlock(GLuint program, GLuint uniformBlockIndex) const {
+ UniformBlockInfoKey key;
+ key.program = program;
+ key.uniformBlockIndex = uniformBlockIndex;
+ UniformBlockInfoMap::const_iterator it =
+ m_uniformBlockInfoMap.find(key);
+ if (it == m_uniformBlockInfoMap.end()) return 0;
+ return it->second.numActiveUniforms;
+}
- if (pixelsize == 0 ) {
- ERR("unknown pixel size: width: %d height: %d format: %d type: %d pack: %d align: %d\n",
- width, height, format, type, pack, alignment);
- }
- size_t linesize = pixelsize * width;
- size_t aligned_linesize = int(linesize / alignment) * alignment;
- if (aligned_linesize < linesize) {
- aligned_linesize += alignment;
- }
- return aligned_linesize * height;
}
GLenum GLClientState::setActiveTextureUnit(GLenum texture)
@@ -315,22 +419,18 @@ int GLClientState::compareTexId(const void* pid, const void* prec)
GLenum GLClientState::bindTexture(GLenum target, GLuint texture,
GLboolean* firstUse)
{
+ assert(m_tex.textureRecs);
GLboolean first = GL_FALSE;
- TextureRec* texrec = NULL;
- if (texture != 0) {
- if (m_tex.textures) {
- texrec = (TextureRec*)bsearch(&texture, m_tex.textures,
- m_tex.numTextures, sizeof(TextureRec), compareTexId);
- }
- if (!texrec) {
- if (!(texrec = addTextureRec(texture, target))) {
- return GL_OUT_OF_MEMORY;
- }
- first = GL_TRUE;
- }
- if (target != texrec->target) {
- return GL_INVALID_OPERATION;
- }
+
+ TextureRec* texrec = getTextureRec(texture);
+ if (!texrec) {
+ texrec = addTextureRec(texture, target);
+ }
+
+ if (texture && target != texrec->target &&
+ (target != GL_TEXTURE_EXTERNAL_OES &&
+ texrec->target != GL_TEXTURE_EXTERNAL_OES)) {
+ ALOGD("%s: issue GL_INVALID_OPERATION: target 0x%x texrectarget 0x%x texture %u", __FUNCTION__, target, texrec->target, texture);
}
switch (target) {
@@ -340,6 +440,18 @@ GLenum GLClientState::bindTexture(GLenum target, GLuint texture,
case GL_TEXTURE_EXTERNAL_OES:
m_tex.activeUnit->texture[TEXTURE_EXTERNAL] = texture;
break;
+ case GL_TEXTURE_CUBE_MAP:
+ m_tex.activeUnit->texture[TEXTURE_CUBE_MAP] = texture;
+ break;
+ case GL_TEXTURE_2D_ARRAY:
+ m_tex.activeUnit->texture[TEXTURE_2D_ARRAY] = texture;
+ break;
+ case GL_TEXTURE_3D:
+ m_tex.activeUnit->texture[TEXTURE_3D] = texture;
+ break;
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ m_tex.activeUnit->texture[TEXTURE_2D_MULTISAMPLE] = texture;
+ break;
}
if (firstUse) {
@@ -349,78 +461,117 @@ GLenum GLClientState::bindTexture(GLenum target, GLuint texture,
return GL_NO_ERROR;
}
-GLClientState::TextureRec* GLClientState::addTextureRec(GLuint id,
- GLenum target)
-{
- if (m_tex.numTextures == m_tex.allocTextures) {
- const GLuint MAX_TEXTURES = 0xFFFFFFFFu;
-
- GLuint newAlloc;
- if (MAX_TEXTURES - m_tex.allocTextures >= m_tex.allocTextures) {
- newAlloc = MAX(4, 2 * m_tex.allocTextures);
- } else {
- if (m_tex.allocTextures == MAX_TEXTURES) {
- return NULL;
- }
- newAlloc = MAX_TEXTURES;
- }
-
- TextureRec* newTextures = (TextureRec*)realloc(m_tex.textures,
- newAlloc * sizeof(TextureRec));
- if (!newTextures) {
- return NULL;
- }
-
- m_tex.textures = newTextures;
- m_tex.allocTextures = newAlloc;
- }
+void GLClientState::setBoundEGLImage(GLenum target, GLeglImageOES image) {
+ GLuint texture = getBoundTexture(target);
+ TextureRec* texrec = getTextureRec(texture);
+ if (!texrec) return;
+ texrec->boundEGLImage = true;
+}
- TextureRec* tex = m_tex.textures + m_tex.numTextures;
- TextureRec* prev = tex - 1;
- while (tex != m_tex.textures && id < prev->id) {
- *tex-- = *prev--;
- }
+TextureRec* GLClientState::addTextureRec(GLuint id, GLenum target)
+{
+ TextureRec* tex = new TextureRec;
tex->id = id;
tex->target = target;
tex->format = -1;
- m_tex.numTextures++;
+ tex->multisamples = 0;
+ tex->immutable = false;
+ tex->boundEGLImage = false;
+ tex->dims = new TextureDims;
+ (*(m_tex.textureRecs))[id] = tex;
return tex;
}
+TextureRec* GLClientState::getTextureRec(GLuint id) const {
+ SharedTextureDataMap::const_iterator it =
+ m_tex.textureRecs->find(id);
+ if (it == m_tex.textureRecs->end()) {
+ return NULL;
+ }
+ return it->second;
+}
+
void GLClientState::setBoundTextureInternalFormat(GLenum target, GLint internalformat) {
GLuint texture = getBoundTexture(target);
- TextureRec* texrec = NULL;
- texrec = (TextureRec*)bsearch(&texture, m_tex.textures,
- m_tex.numTextures,
- sizeof(TextureRec),
- compareTexId);
+ TextureRec* texrec = getTextureRec(texture);
if (!texrec) return;
texrec->internalformat = internalformat;
}
void GLClientState::setBoundTextureFormat(GLenum target, GLenum format) {
GLuint texture = getBoundTexture(target);
- TextureRec* texrec = NULL;
- texrec = (TextureRec*)bsearch(&texture, m_tex.textures,
- m_tex.numTextures,
- sizeof(TextureRec),
- compareTexId);
+ TextureRec* texrec = getTextureRec(texture);
if (!texrec) return;
texrec->format = format;
}
void GLClientState::setBoundTextureType(GLenum target, GLenum type) {
GLuint texture = getBoundTexture(target);
- TextureRec* texrec = NULL;
- texrec = (TextureRec*)bsearch(&texture, m_tex.textures,
- m_tex.numTextures,
- sizeof(TextureRec),
- compareTexId);
+ TextureRec* texrec = getTextureRec(texture);
if (!texrec) return;
texrec->type = type;
}
+void GLClientState::setBoundTextureDims(GLenum target, GLsizei level, GLsizei width, GLsizei height, GLsizei depth) {
+ GLuint texture = getBoundTexture(target);
+ TextureRec* texrec = getTextureRec(texture);
+ if (!texrec) {
+ return;
+ }
+
+ if (level == -1) {
+ GLsizei curr_width = width;
+ GLsizei curr_height = height;
+ GLsizei curr_depth = depth;
+ GLsizei curr_level = 0;
+
+ while (true) {
+ texrec->dims->widths[curr_level] = curr_width;
+ texrec->dims->heights[curr_level] = curr_height;
+ texrec->dims->depths[curr_level] = curr_depth;
+ if (curr_width >> 1 == 0 &&
+ curr_height >> 1 == 0 &&
+ ((target == GL_TEXTURE_3D && curr_depth == 0) ||
+ true)) {
+ break;
+ }
+ curr_width = (curr_width >> 1) ? (curr_width >> 1) : 1;
+ curr_height = (curr_height >> 1) ? (curr_height >> 1) : 1;
+ if (target == GL_TEXTURE_3D) {
+ curr_depth = (curr_depth >> 1) ? (curr_depth >> 1) : 1;
+ }
+ curr_level++;
+ }
+
+ } else {
+ texrec->dims->widths[level] = width;
+ texrec->dims->heights[level] = height;
+ texrec->dims->depths[level] = depth;
+ }
+}
+
+void GLClientState::setBoundTextureSamples(GLenum target, GLsizei samples) {
+ GLuint texture = getBoundTexture(target);
+ TextureRec* texrec = getTextureRec(texture);
+ if (!texrec) return;
+ texrec->multisamples = samples;
+}
+
+void GLClientState::setBoundTextureImmutableFormat(GLenum target) {
+ GLuint texture = getBoundTexture(target);
+ TextureRec* texrec = getTextureRec(texture);
+ if (!texrec) return;
+ texrec->immutable = true;
+}
+
+bool GLClientState::isBoundTextureImmutableFormat(GLenum target) const {
+ GLuint texture = getBoundTexture(target);
+ TextureRec* texrec = getTextureRec(texture);
+ if (!texrec) return false;
+ return texrec->immutable;
+}
+
GLuint GLClientState::getBoundTexture(GLenum target) const
{
switch (target) {
@@ -428,6 +579,14 @@ GLuint GLClientState::getBoundTexture(GLenum target) const
return m_tex.activeUnit->texture[TEXTURE_2D];
case GL_TEXTURE_EXTERNAL_OES:
return m_tex.activeUnit->texture[TEXTURE_EXTERNAL];
+ case GL_TEXTURE_CUBE_MAP:
+ return m_tex.activeUnit->texture[TEXTURE_CUBE_MAP];
+ case GL_TEXTURE_2D_ARRAY:
+ return m_tex.activeUnit->texture[TEXTURE_2D_ARRAY];
+ case GL_TEXTURE_3D:
+ return m_tex.activeUnit->texture[TEXTURE_3D];
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ return m_tex.activeUnit->texture[TEXTURE_2D_MULTISAMPLE];
default:
return 0;
}
@@ -508,14 +667,13 @@ void GLClientState::deleteTextures(GLsizei n, const GLuint* textures)
// - could swap deleted textures to the end and re-sort.
TextureRec* texrec;
for (const GLuint* texture = textures; texture != textures + n; texture++) {
- texrec = (TextureRec*)bsearch(texture, m_tex.textures,
- m_tex.numTextures, sizeof(TextureRec), compareTexId);
+ texrec = getTextureRec(*texture);
+ if (texrec && texrec->dims) {
+ delete texrec->dims;
+ }
if (texrec) {
- const TextureRec* end = m_tex.textures + m_tex.numTextures;
- memmove(texrec, texrec + 1,
- (end - texrec - 1) * sizeof(TextureRec));
- m_tex.numTextures--;
-
+ m_tex.textureRecs->erase(*texture);
+ delete texrec;
for (TextureUnit* unit = m_tex.unit;
unit != m_tex.unit + MAX_TEXTURE_UNITS;
unit++)
@@ -632,29 +790,61 @@ GLenum GLClientState::queryRboFormat(GLuint rbo_name) const {
}
GLint GLClientState::queryTexInternalFormat(GLuint tex_name) const {
- TextureRec* texrec = NULL;
- texrec = (TextureRec*)bsearch(&tex_name, m_tex.textures,
- m_tex.numTextures, sizeof(TextureRec), compareTexId);
+ TextureRec* texrec = getTextureRec(tex_name);
if (!texrec) return -1;
return texrec->internalformat;
}
+GLsizei GLClientState::queryTexWidth(GLsizei level, GLuint tex_name) const {
+ TextureRec* texrec = getTextureRec(tex_name);
+ if (!texrec) {
+ return 0;
+ }
+ return texrec->dims->widths[level];
+}
+
+GLsizei GLClientState::queryTexHeight(GLsizei level, GLuint tex_name) const {
+ TextureRec* texrec = getTextureRec(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);
+ if (!texrec) return 0;
+ return texrec->dims->depths[level];
+}
+
+bool GLClientState::queryTexEGLImageBacked(GLuint tex_name) const {
+ TextureRec* texrec = getTextureRec(tex_name);
+ if (!texrec) return false;
+ return texrec->boundEGLImage;
+}
+
GLenum GLClientState::queryTexFormat(GLuint tex_name) const {
- TextureRec* texrec = NULL;
- texrec = (TextureRec*)bsearch(&tex_name, m_tex.textures,
- m_tex.numTextures, sizeof(TextureRec), compareTexId);
+ TextureRec* texrec = getTextureRec(tex_name);
if (!texrec) return -1;
return texrec->format;
}
GLenum GLClientState::queryTexType(GLuint tex_name) const {
- TextureRec* texrec = NULL;
- texrec = (TextureRec*)bsearch(&tex_name, m_tex.textures,
- m_tex.numTextures, sizeof(TextureRec), compareTexId);
+ TextureRec* texrec = getTextureRec(tex_name);
if (!texrec) return -1;
return texrec->type;
}
+GLsizei GLClientState::queryTexSamples(GLuint tex_name) const {
+ TextureRec* texrec = getTextureRec(tex_name);
+ if (!texrec) return 0;
+ return texrec->multisamples;
+}
+
+GLenum GLClientState::queryTexLastBoundTarget(GLuint tex_name) const {
+ TextureRec* texrec = getTextureRec(tex_name);
+ if (!texrec) return GL_NONE;
+ return texrec->target;
+}
+
void GLClientState::getBoundFramebufferFormat(
GLenum attachment, FboFormatInfo* res_info) const {
const FboProps& props = boundFboProps_const();
diff --git a/shared/OpenglCodecCommon/GLClientState.h b/shared/OpenglCodecCommon/GLClientState.h
index 9eee2f16..e1fb64dc 100644
--- a/shared/OpenglCodecCommon/GLClientState.h
+++ b/shared/OpenglCodecCommon/GLClientState.h
@@ -22,6 +22,8 @@
#define GL_APIENTRYP
#endif
+#include "TextureSharedData.h"
+
#include <GLES/gl.h>
#include <GLES/glext.h>
#include <GLES2/gl2.h>
@@ -33,6 +35,7 @@
#include "codec_defs.h"
#include <vector>
+#include <map>
#include <set>
// Tracking framebuffer objects:
@@ -83,6 +86,7 @@ struct FboFormatInfo {
GLint tex_internalformat;
GLenum tex_format;
GLenum tex_type;
+ GLsizei tex_multisamples;
};
class GLClientState {
@@ -120,11 +124,22 @@ public:
typedef struct {
int unpack_alignment;
+
+ int unpack_row_length;
+ int unpack_image_height;
+ int unpack_skip_pixels;
+ int unpack_skip_rows;
+ int unpack_skip_images;
+
int pack_alignment;
+
+ int pack_row_length;
+ int pack_skip_pixels;
+ int pack_skip_rows;
} PixelStoreState;
enum {
- MAX_TEXTURE_UNITS = 32,
+ MAX_TEXTURE_UNITS = 256,
};
public:
@@ -185,7 +200,9 @@ public:
}
return ret;
}
- size_t pixelDataSize(GLsizei width, GLsizei height, GLenum format, GLenum type, int pack) const;
+ size_t pixelDataSize(GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, int pack) const;
+ size_t pboNeededDataSize(GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, int pack) const;
+ size_t clearBufferNumElts(GLenum buffer) const;
void setCurrentProgram(GLint program) { m_currentProgram = program; }
GLint currentProgram() const { return m_currentProgram; }
@@ -232,9 +249,18 @@ public:
// For accurate error detection, bindTexture should be called for *all*
// targets, not just 2D and EXTERNAL_OES.
GLenum bindTexture(GLenum target, GLuint texture, GLboolean* firstUse);
+ void setBoundEGLImage(GLenum target, GLeglImageOES image);
// Return the texture currently bound to GL_TEXTURE_(2D|EXTERNAL_OES).
GLuint getBoundTexture(GLenum target) const;
+ // Other publicly-visible texture queries
+ GLenum queryTexLastBoundTarget(GLuint name) const;
+ GLenum queryTexFormat(GLuint name) const;
+ GLint queryTexInternalFormat(GLuint name) const;
+ GLsizei queryTexWidth(GLsizei level, GLuint name) const;
+ GLsizei queryTexHeight(GLsizei level, GLuint name) const;
+ GLsizei queryTexDepth(GLsizei level, GLuint name) const;
+ bool queryTexEGLImageBacked(GLuint name) const;
// For AMD GPUs, it is easy for the emulator to segfault
// (esp. in dEQP) when a cube map is defined using glCopyTexImage2D
@@ -253,6 +279,12 @@ public:
void setBoundTextureInternalFormat(GLenum target, GLint format);
void setBoundTextureFormat(GLenum target, GLenum format);
void setBoundTextureType(GLenum target, GLenum type);
+ void setBoundTextureDims(GLenum target, GLsizei level, GLsizei width, GLsizei height, GLsizei depth);
+ void setBoundTextureSamples(GLenum target, GLsizei samples);
+
+ // glTexStorage2D disallows any change in texture format after it is set for a particular texture.
+ void setBoundTextureImmutableFormat(GLenum target);
+ bool isBoundTextureImmutableFormat(GLenum target) const;
// glDeleteTextures(...)
// Remove references to the to-be-deleted textures.
@@ -286,6 +318,7 @@ public:
// FBO attachments in general
bool attachmentHasObject(GLenum attachment) const;
+ void setTextureData(SharedTextureDataMap* sharedTexData);
// set eglsurface property on default framebuffer
// if coming from eglMakeCurrent
void fromMakeCurrent();
@@ -299,6 +332,8 @@ public:
private:
PixelStoreState m_pixelStore;
VertexAttribState *m_states;
+ int m_glesMajorVersion;
+ int m_glesMinorVersion;
int m_maxVertexAttribs;
bool m_maxVertexAttribsDirty;
int m_nLocations;
@@ -312,25 +347,21 @@ private:
enum TextureTarget {
TEXTURE_2D = 0,
TEXTURE_EXTERNAL = 1,
+ TEXTURE_CUBE_MAP = 2,
+ TEXTURE_2D_ARRAY = 3,
+ TEXTURE_3D = 4,
+ TEXTURE_2D_MULTISAMPLE = 5,
TEXTURE_TARGET_COUNT
};
struct TextureUnit {
unsigned int enables;
GLuint texture[TEXTURE_TARGET_COUNT];
};
- struct TextureRec {
- GLuint id;
- GLenum target;
- GLint internalformat;
- GLenum format;
- GLenum type;
- };
struct TextureState {
TextureUnit unit[MAX_TEXTURE_UNITS];
TextureUnit* activeUnit;
- TextureRec* textures;
- GLuint numTextures;
- GLuint allocTextures;
+ // Initialized from shared group.
+ SharedTextureDataMap* textureRecs;
};
TextureState m_tex;
@@ -388,12 +419,12 @@ private:
// Querying framebuffer format
GLenum queryRboFormat(GLuint name) const;
- GLint queryTexInternalFormat(GLuint name) const;
- GLenum queryTexFormat(GLuint name) const;
GLenum queryTexType(GLuint name) const;
+ GLsizei queryTexSamples(GLuint name) const;
static int compareTexId(const void* pid, const void* prec);
TextureRec* addTextureRec(GLuint id, GLenum target);
+ TextureRec* getTextureRec(GLuint id) const;
public:
void getClientStatePointer(GLenum pname, GLvoid** params);
diff --git a/shared/OpenglCodecCommon/GLESTextureUtils.cpp b/shared/OpenglCodecCommon/GLESTextureUtils.cpp
new file mode 100644
index 00000000..1aef8cb4
--- /dev/null
+++ b/shared/OpenglCodecCommon/GLESTextureUtils.cpp
@@ -0,0 +1,287 @@
+#include "GLESTextureUtils.h"
+
+#include "glUtils.h"
+
+#include <cutils/log.h>
+
+namespace GLESTextureUtils {
+
+// Based on computations in
+// https://swiftshader.googlesource.com/SwiftShader/+/master/src/OpenGL/common/Image.cpp
+// such as Image::loadImageData,
+// ComputePitch/ComputePackingOffset
+
+#define HIGHEST_MULTIPLE_OF(align, x) \
+ (( ( x ) + ( align ) - 1) & ~( ( align ) - 1)) \
+
+static int computePixelSize(GLenum format, GLenum type) {
+
+#define FORMAT_ERROR(format, type) \
+ ALOGE("%s:%d unknown format/type 0x%x 0x%x", __FUNCTION__, __LINE__, format, type) \
+
+ switch(type) {
+ case GL_BYTE:
+ switch(format) {
+ case GL_R8:
+ case GL_R8I:
+ case GL_R8_SNORM:
+ case GL_RED: return sizeof(char);
+ case GL_RED_INTEGER: return sizeof(char);
+ case GL_RG8:
+ case GL_RG8I:
+ case GL_RG8_SNORM:
+ case GL_RG: return sizeof(char) * 2;
+ case GL_RG_INTEGER: return sizeof(char) * 2;
+ case GL_RGB8:
+ case GL_RGB8I:
+ case GL_RGB8_SNORM:
+ case GL_RGB: return sizeof(char) * 3;
+ case GL_RGB_INTEGER: return sizeof(char) * 3;
+ case GL_RGBA8:
+ case GL_RGBA8I:
+ case GL_RGBA8_SNORM:
+ case GL_RGBA: return sizeof(char) * 4;
+ case GL_RGBA_INTEGER: return sizeof(char) * 4;
+ default: FORMAT_ERROR(format, type);
+ }
+ break;
+ case GL_UNSIGNED_BYTE:
+ switch(format) {
+ case GL_R8:
+ case GL_R8UI:
+ case GL_RED: return sizeof(unsigned char);
+ case GL_RED_INTEGER: return sizeof(unsigned char);
+ case GL_ALPHA8_EXT:
+ case GL_ALPHA: return sizeof(unsigned char);
+ case GL_LUMINANCE8_EXT:
+ case GL_LUMINANCE: return sizeof(unsigned char);
+ case GL_LUMINANCE8_ALPHA8_EXT:
+ case GL_LUMINANCE_ALPHA: return sizeof(unsigned char) * 2;
+ case GL_RG8:
+ case GL_RG8UI:
+ case GL_RG: return sizeof(unsigned char) * 2;
+ case GL_RG_INTEGER: return sizeof(unsigned char) * 2;
+ case GL_RGB8:
+ case GL_RGB8UI:
+ case GL_SRGB8:
+ case GL_RGB: return sizeof(unsigned char) * 3;
+ case GL_RGB_INTEGER: return sizeof(unsigned char) * 3;
+ case GL_RGBA8:
+ case GL_RGBA8UI:
+ case GL_SRGB8_ALPHA8:
+ case GL_RGBA: return sizeof(unsigned char) * 4;
+ case GL_RGBA_INTEGER: return sizeof(unsigned char) * 4;
+ case GL_BGRA_EXT:
+ case GL_BGRA8_EXT: return sizeof(unsigned char)* 4;
+ default: FORMAT_ERROR(format, type);
+ }
+ break;
+ case GL_SHORT:
+ switch(format) {
+ case GL_R16I:
+ case GL_RED_INTEGER: return sizeof(short);
+ case GL_RG16I:
+ case GL_RG_INTEGER: return sizeof(short) * 2;
+ case GL_RGB16I:
+ case GL_RGB_INTEGER: return sizeof(short) * 3;
+ case GL_RGBA16I:
+ case GL_RGBA_INTEGER: return sizeof(short) * 4;
+ default: FORMAT_ERROR(format, type);
+ }
+ break;
+ case GL_UNSIGNED_SHORT:
+ switch(format) {
+ case GL_DEPTH_COMPONENT16:
+ case GL_DEPTH_COMPONENT: return sizeof(unsigned short);
+ case GL_R16UI:
+ case GL_RED_INTEGER: return sizeof(unsigned short);
+ case GL_RG16UI:
+ case GL_RG_INTEGER: return sizeof(unsigned short) * 2;
+ case GL_RGB16UI:
+ case GL_RGB_INTEGER: return sizeof(unsigned short) * 3;
+ case GL_RGBA16UI:
+ case GL_RGBA_INTEGER: return sizeof(unsigned short) * 4;
+ default: FORMAT_ERROR(format, type);
+ }
+ break;
+ case GL_INT:
+ switch(format) {
+ case GL_R32I:
+ case GL_RED_INTEGER: return sizeof(int);
+ case GL_RG32I:
+ case GL_RG_INTEGER: return sizeof(int) * 2;
+ case GL_RGB32I:
+ case GL_RGB_INTEGER: return sizeof(int) * 3;
+ case GL_RGBA32I:
+ case GL_RGBA_INTEGER: return sizeof(int) * 4;
+ default: FORMAT_ERROR(format, type);
+ }
+ break;
+ case GL_UNSIGNED_INT:
+ switch(format) {
+ case GL_DEPTH_COMPONENT16:
+ case GL_DEPTH_COMPONENT24:
+ case GL_DEPTH_COMPONENT32_OES:
+ case GL_DEPTH_COMPONENT: return sizeof(unsigned int);
+ case GL_R32UI:
+ case GL_RED_INTEGER: return sizeof(unsigned int);
+ case GL_RG32UI:
+ case GL_RG_INTEGER: return sizeof(unsigned int) * 2;
+ case GL_RGB32UI:
+ case GL_RGB_INTEGER: return sizeof(unsigned int) * 3;
+ case GL_RGBA32UI:
+ case GL_RGBA_INTEGER: return sizeof(unsigned int) * 4;
+ default: FORMAT_ERROR(format, type);
+ }
+ break;
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ case GL_UNSIGNED_SHORT_5_6_5:
+ case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
+ case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
+ return sizeof(unsigned short);
+ case GL_UNSIGNED_INT_10F_11F_11F_REV:
+ case GL_UNSIGNED_INT_5_9_9_9_REV:
+ case GL_UNSIGNED_INT_2_10_10_10_REV:
+ case GL_UNSIGNED_INT_24_8_OES:
+ return sizeof(unsigned int);
+ case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
+ return sizeof(float) + sizeof(unsigned int);
+ case GL_FLOAT:
+ switch(format) {
+ case GL_DEPTH_COMPONENT32F:
+ case GL_DEPTH_COMPONENT: return sizeof(float);
+ case GL_ALPHA32F_EXT:
+ case GL_ALPHA: return sizeof(float);
+ case GL_LUMINANCE32F_EXT:
+ case GL_LUMINANCE: return sizeof(float);
+ case GL_LUMINANCE_ALPHA32F_EXT:
+ case GL_LUMINANCE_ALPHA: return sizeof(float) * 2;
+ case GL_RED: return sizeof(float);
+ case GL_R32F: return sizeof(float);
+ case GL_RG: return sizeof(float) * 2;
+ case GL_RG32F: return sizeof(float) * 2;
+ case GL_RGB: return sizeof(float) * 3;
+ case GL_RGB32F: return sizeof(float) * 3;
+ case GL_RGBA: return sizeof(float) * 4;
+ case GL_RGBA32F: return sizeof(float) * 4;
+ default: FORMAT_ERROR(format, type);
+ }
+ break;
+ case GL_HALF_FLOAT:
+ case GL_HALF_FLOAT_OES:
+ switch(format) {
+ case GL_ALPHA16F_EXT:
+ case GL_ALPHA: return sizeof(unsigned short);
+ case GL_LUMINANCE16F_EXT:
+ case GL_LUMINANCE: return sizeof(unsigned short);
+ case GL_LUMINANCE_ALPHA16F_EXT:
+ case GL_LUMINANCE_ALPHA: return sizeof(unsigned short) * 2;
+ case GL_RED: return sizeof(unsigned short);
+ case GL_R16F: return sizeof(unsigned short);
+ case GL_RG: return sizeof(unsigned short) * 2;
+ case GL_RG16F: return sizeof(unsigned short) * 2;
+ case GL_RGB: return sizeof(unsigned short) * 3;
+ case GL_RGB16F: return sizeof(unsigned short) * 3;
+ case GL_RGBA: return sizeof(unsigned short) * 4;
+ case GL_RGBA16F: return sizeof(unsigned short) * 4;
+ default: FORMAT_ERROR(format, type);
+ }
+ break;
+ default: FORMAT_ERROR(format, type);
+ }
+
+ return 0;
+}
+
+static int computePitch(GLsizei inputWidth, GLenum format, GLenum type, int align) {
+ GLsizei unaligned_width = computePixelSize(format, type) * inputWidth;
+ return HIGHEST_MULTIPLE_OF(align, unaligned_width);
+}
+
+static int computePackingOffset(GLenum format, GLenum type, GLsizei width, GLsizei height, int align, int skipPixels, int skipRows, int skipImages) {
+ GLsizei alignedPitch = computePitch(width, format, type, align);
+ int packingOffsetRows =
+ (skipImages * height + skipRows);
+ return packingOffsetRows * alignedPitch + skipPixels * computePixelSize(format, type);
+}
+
+void computeTextureStartEnd(
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type,
+ int unpackAlignment,
+ int unpackRowLength,
+ int unpackImageHeight,
+ int unpackSkipPixels,
+ int unpackSkipRows,
+ int unpackSkipImages,
+ int* start,
+ int* end) {
+
+ GLsizei inputWidth = (unpackRowLength == 0) ? width : unpackRowLength;
+ GLsizei inputPitch = computePitch(inputWidth, format, type, unpackAlignment);
+ GLsizei inputHeight = (unpackImageHeight == 0) ? height : unpackImageHeight;
+
+ ALOGV("%s: input idim %d %d %d w p h %d %d %d:", __FUNCTION__, width, height, depth, inputWidth, inputPitch, inputHeight);
+
+ int startVal = computePackingOffset(format, type, inputWidth, inputHeight, unpackAlignment, unpackSkipPixels, unpackSkipRows, unpackSkipImages);
+ int endVal = startVal + inputPitch * inputHeight * depth;
+
+ if (start) *start = startVal;
+ if (end) *end = endVal;
+
+ ALOGV("%s: start/end: %d %d", __FUNCTION__, *start, *end);
+
+}
+
+int computeTotalImageSize(
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type,
+ int unpackAlignment,
+ int unpackRowLength,
+ int unpackImageHeight,
+ int unpackSkipPixels,
+ int unpackSkipRows,
+ int unpackSkipImages) {
+
+ int start, end;
+ computeTextureStartEnd(
+ width, height, depth,
+ format, type,
+ unpackAlignment,
+ unpackRowLength,
+ unpackImageHeight,
+ unpackSkipPixels,
+ unpackSkipRows,
+ unpackSkipImages,
+ &start,
+ &end);
+ return end;
+}
+
+int computeNeededBufferSize(
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type,
+ int unpackAlignment,
+ int unpackRowLength,
+ int unpackImageHeight,
+ int unpackSkipPixels,
+ int unpackSkipRows,
+ int unpackSkipImages) {
+
+ int start, end;
+ computeTextureStartEnd(
+ width, height, depth,
+ format, type,
+ unpackAlignment,
+ unpackRowLength,
+ unpackImageHeight,
+ unpackSkipPixels,
+ unpackSkipRows,
+ unpackSkipImages,
+ &start,
+ &end);
+ return end - start;
+}
+
+} // namespace GLESTextureUtils
diff --git a/shared/OpenglCodecCommon/GLESTextureUtils.h b/shared/OpenglCodecCommon/GLESTextureUtils.h
new file mode 100644
index 00000000..906e5904
--- /dev/null
+++ b/shared/OpenglCodecCommon/GLESTextureUtils.h
@@ -0,0 +1,42 @@
+#ifndef GLES_TEXTURE_UTILS_H
+#define GLES_TEXTURE_UTILS_H
+
+#include <GLES3/gl31.h>
+
+namespace GLESTextureUtils {
+
+void computeTextureStartEnd(
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type,
+ int unpackAlignment,
+ int unpackRowLength,
+ int unpackImageHeight,
+ int unpackSkipPixels,
+ int unpackSkipRows,
+ int unpackSkipImages,
+ int* start,
+ int* end);
+
+int computeTotalImageSize(
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type,
+ int unpackAlignment,
+ int unpackRowLength,
+ int unpackImageHeight,
+ int unpackSkipPixels,
+ int unpackSkipRows,
+ int unpackSkipImages);
+
+int computeNeededBufferSize(
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type,
+ int unpackAlignment,
+ int unpackRowLength,
+ int unpackImageHeight,
+ int unpackSkipPixels,
+ int unpackSkipRows,
+ int unpackSkipImages);
+
+
+} // namespace GLESTextureUtils
+#endif
diff --git a/shared/OpenglCodecCommon/GLSharedGroup.cpp b/shared/OpenglCodecCommon/GLSharedGroup.cpp
index 3b5211f6..1b8facf4 100755
--- a/shared/OpenglCodecCommon/GLSharedGroup.cpp
+++ b/shared/OpenglCodecCommon/GLSharedGroup.cpp
@@ -252,6 +252,10 @@ BufferData * GLSharedGroup::getBufferData(GLuint bufferId)
return m_buffers.valueFor(bufferId);
}
+SharedTextureDataMap* GLSharedGroup::getTextureData() {
+ return &m_textureRecs;
+}
+
void GLSharedGroup::addBufferData(GLuint bufferId, GLsizeiptr size, void * data)
{
android::AutoMutex _lock(m_lock);
diff --git a/shared/OpenglCodecCommon/GLSharedGroup.h b/shared/OpenglCodecCommon/GLSharedGroup.h
index 4057b52b..2de300f8 100755
--- a/shared/OpenglCodecCommon/GLSharedGroup.h
+++ b/shared/OpenglCodecCommon/GLSharedGroup.h
@@ -22,11 +22,14 @@
#define GL_APIENTRYP
#endif
+#include "TextureSharedData.h"
+
#include <GLES/gl.h>
#include <GLES/glext.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
+#include <map>
#include <stdio.h>
#include <stdlib.h>
#include "ErrorLog.h"
@@ -101,6 +104,7 @@ struct ShaderData {
class GLSharedGroup {
private:
+ SharedTextureDataMap m_textureRecs;
android::DefaultKeyedVector<GLuint, BufferData*> m_buffers;
android::DefaultKeyedVector<GLuint, ProgramData*> m_programs;
android::DefaultKeyedVector<GLuint, ShaderData*> m_shaders;
@@ -114,6 +118,7 @@ public:
~GLSharedGroup();
bool isObject(GLuint obj);
BufferData * getBufferData(GLuint bufferId);
+ SharedTextureDataMap* getTextureData();
void addBufferData(GLuint bufferId, GLsizeiptr size, void * data);
void updateBufferData(GLuint bufferId, GLsizeiptr size, void * data);
GLenum subUpdateBufferData(GLuint bufferId, GLintptr offset, GLsizeiptr size, void * data);
diff --git a/shared/OpenglCodecCommon/TextureSharedData.h b/shared/OpenglCodecCommon/TextureSharedData.h
new file mode 100644
index 00000000..1372f7a0
--- /dev/null
+++ b/shared/OpenglCodecCommon/TextureSharedData.h
@@ -0,0 +1,42 @@
+/*
+* Copyright (C) 2016 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.
+*/
+#ifndef _GL_TEXTURE_SHARED_DATA_H_
+#define _GL_TEXTURE_SHARED_DATA_H_
+
+#include <GLES/gl.h>
+#include <map>
+
+struct TextureDims {
+ std::map<GLsizei, GLsizei> widths;
+ std::map<GLsizei, GLsizei> heights;
+ std::map<GLsizei, GLsizei> depths;
+};
+
+struct TextureRec {
+ GLuint id;
+ GLenum target;
+ GLint internalformat;
+ GLenum format;
+ GLenum type;
+ GLsizei multisamples;
+ TextureDims* dims;
+ bool immutable;
+ bool boundEGLImage;
+};
+
+typedef std::map<GLuint, TextureRec*> SharedTextureDataMap;
+
+#endif