diff options
author | Lingfeng Yang <lfy@google.com> | 2017-01-10 14:54:38 -0800 |
---|---|---|
committer | Lingfeng Yang <lfy@google.com> | 2017-01-10 22:06:09 -0800 |
commit | 74e29295ec43efde4365f08f20d7e1515c182b99 (patch) | |
tree | dfc6c420d7d76b6799e154e3272f936e2f12c5ff /shared/OpenglCodecCommon | |
parent | e6556dcf96ef0b859fe04d8caf7c40fdd6d8d254 (diff) | |
download | goldfish-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.mk | 1 | ||||
-rw-r--r-- | shared/OpenglCodecCommon/GLClientState.cpp | 402 | ||||
-rw-r--r-- | shared/OpenglCodecCommon/GLClientState.h | 59 | ||||
-rw-r--r-- | shared/OpenglCodecCommon/GLESTextureUtils.cpp | 287 | ||||
-rw-r--r-- | shared/OpenglCodecCommon/GLESTextureUtils.h | 42 | ||||
-rwxr-xr-x | shared/OpenglCodecCommon/GLSharedGroup.cpp | 4 | ||||
-rwxr-xr-x | shared/OpenglCodecCommon/GLSharedGroup.h | 5 | ||||
-rw-r--r-- | shared/OpenglCodecCommon/TextureSharedData.h | 42 |
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 |