Snap for 8701376 from ef8778a609108985745ab3b94cbbc64f6a763f5c to mainline-appsearch-release
Change-Id: I2e4cbc3d0c0a851e0ee198a9361f11958630cc33
diff --git a/shared/OpenglCodecCommon/GLClientState.cpp b/shared/OpenglCodecCommon/GLClientState.cpp
index 903a437..852f36a 100644
--- a/shared/OpenglCodecCommon/GLClientState.cpp
+++ b/shared/OpenglCodecCommon/GLClientState.cpp
@@ -123,7 +123,7 @@
m_tex.activeUnit = &m_tex.unit[0];
m_tex.textureRecs = NULL;
- mRboState.boundRenderbuffer = 0;
+ mRboState.boundRenderbuffer = nullptr;
mFboState.boundDrawFramebuffer = 0;
mFboState.boundReadFramebuffer = 0;
@@ -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,25 +1924,27 @@
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:
- id = getFboAttachmentRboId(target, attachment);
+ rbo = getFboAttachmentRbo(target, attachment);
if (!fbo_format_info.rb_external) {
- if (0 == queryRboWidth(id) || 0 == queryRboHeight(id)) {
+ if (!rbo || 0 == rbo->width || 0 == rbo->height) {
ALOGD("%s: rbo has zero dimension\n", __func__);
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
}
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);
@@ -2053,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++)
@@ -2090,25 +2101,27 @@
}
void GLClientState::removeRenderbuffers(GLsizei n, const GLuint* renderbuffers) {
- std::vector<GLuint> to_remove;
- for (size_t i = 0; i < n; i++) {
- if (renderbuffers[i] != 0) { // Never remove the zero rb.
- to_remove.push_back(renderbuffers[i]);
- setFboCompletenessDirtyForRbo(renderbuffers[i]);
- }
- }
-
+ std::vector<std::shared_ptr<RboProps>> to_remove;
bool unbindCurrent = false;
{
RenderbufferInfo::ScopedView view(mRboState.rboData);
- for (size_t i = 0; i < to_remove.size(); i++) {
- view.unref(to_remove[i]);
+ for (size_t i = 0; i < n; i++) {
+ if (renderbuffers[i] != 0) { // Never remove the zero rb.
+ auto rboPtr = view.get_shared_ptr(renderbuffers[i]);
+ if (!rboPtr) {
+ continue;
+ }
+ to_remove.push_back(rboPtr);
+ setFboCompletenessDirtyForRbo(rboPtr);
+ }
}
+
for (size_t i = 0; i < to_remove.size(); i++) {
- if (mRboState.boundRenderbuffer == renderbuffers[i]) {
+ if (mRboState.boundRenderbuffer == to_remove[i]) {
unbindCurrent = true;
break;
}
+ view.remove(to_remove[i]->id);
}
}
@@ -2128,98 +2141,40 @@
(void)target; // Must be GL_RENDERBUFFER
RenderbufferInfo::ScopedView view(mRboState.rboData);
- if (name == mRboState.boundRenderbuffer) {
- return;
- }
- view.unref(mRboState.boundRenderbuffer);
-
- mRboState.boundRenderbuffer = name;
-
- if (!name) return;
-
- view.bind(name);
+ mRboState.boundRenderbuffer = view.bind(name);
}
GLuint GLClientState::boundRenderbuffer() const {
- return mRboState.boundRenderbuffer;
+ return mRboState.boundRenderbuffer->id;
}
void GLClientState::setBoundRenderbufferFormat(GLenum format) {
- RenderbufferInfo::ScopedView view(mRboState.rboData);
- RboProps* props = view.get(mRboState.boundRenderbuffer);
- if (!props) return;
- props->format = format;
+ mRboState.boundRenderbuffer->format = format;
}
void GLClientState::setBoundRenderbufferSamples(GLsizei samples) {
- RenderbufferInfo::ScopedView view(mRboState.rboData);
- RboProps* props = view.get(mRboState.boundRenderbuffer);
- if (!props) return;
- props->multisamples = samples;
+ mRboState.boundRenderbuffer->multisamples = samples;
}
void GLClientState::setBoundRenderbufferDimensions(GLsizei width, GLsizei height) {
- RenderbufferInfo::ScopedView view(mRboState.rboData);
- RboProps* props = view.get(mRboState.boundRenderbuffer);
- if (!props) return;
- props->width = width;
- props->height = height;
+ mRboState.boundRenderbuffer->width = width;
+ mRboState.boundRenderbuffer->height = height;
}
void GLClientState::setBoundRenderbufferEGLImageBacked() {
- RenderbufferInfo::ScopedView view(mRboState.rboData);
- RboProps* props = view.get(mRboState.boundRenderbuffer);
- if (!props) return;
- props->boundEGLImage = true;
+ mRboState.boundRenderbuffer->boundEGLImage = true;
}
// FBO//////////////////////////////////////////////////////////////////////////
-// Format querying
-
-GLenum GLClientState::queryRboFormat(GLuint rbo_name) const {
- RenderbufferInfo::ScopedView view(mRboState.rboData);
- const RboProps* props = view.get(rbo_name);
- if (!props) return 0;
- return props->format;
-}
-
-GLsizei GLClientState::queryRboSamples(GLuint rbo_name) const {
- RenderbufferInfo::ScopedView view(mRboState.rboData);
- const RboProps* props = view.get(rbo_name);
- if (!props) return 0;
- return props->multisamples;
-}
-
-GLsizei GLClientState::queryRboWidth(GLuint rbo_name) const {
- RenderbufferInfo::ScopedView view(mRboState.rboData);
- const RboProps* props = view.get(rbo_name);
- if (!props) return 0;
- return props->width;
-}
-
-GLsizei GLClientState::queryRboHeight(GLuint rbo_name) const {
- RenderbufferInfo::ScopedView view(mRboState.rboData);
- const RboProps* props = view.get(rbo_name);
- if (!props) return 0;
- return props->height;
-}
-
-bool GLClientState::queryRboEGLImageBacked(GLuint rbo_name) const {
- RenderbufferInfo::ScopedView view(mRboState.rboData);
- const RboProps* props = view.get(rbo_name);
- if (!props) return 0;
- return props->boundEGLImage;
-}
-
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;
}
@@ -2227,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;
}
@@ -2289,29 +2244,23 @@
if (colorAttachmentIndex != -1) {
if (props.colorAttachmenti_hasRbo[colorAttachmentIndex]) {
res_info->type = FBO_ATTACHMENT_RENDERBUFFER;
- res_info->rb_format =
- queryRboFormat(
- props.colorAttachmenti_rbos[colorAttachmentIndex]);
+ res_info->rb_format = props.colorAttachmenti_rbos[colorAttachmentIndex]->format;
res_info->rb_multisamples =
- queryRboSamples(
- props.colorAttachmenti_rbos[colorAttachmentIndex]);
+ props.colorAttachmenti_rbos[colorAttachmentIndex]->multisamples;
res_info->rb_external =
- queryRboEGLImageBacked(
- props.colorAttachmenti_rbos[colorAttachmentIndex]);
+ 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 {
@@ -2323,21 +2272,16 @@
case GL_DEPTH_ATTACHMENT:
if (props.depthAttachment_hasRbo) {
res_info->type = FBO_ATTACHMENT_RENDERBUFFER;
- res_info->rb_format = queryRboFormat(props.depthAttachment_rbo);
- res_info->rb_multisamples =
- queryRboSamples(
- props.depthAttachment_rbo);
- res_info->rb_external =
- queryRboEGLImageBacked(
- props.depthAttachment_rbo);
+ res_info->rb_format = props.depthAttachment_rbo->format;
+ res_info->rb_multisamples = props.depthAttachment_rbo->multisamples;
+ 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 {
@@ -2347,21 +2291,16 @@
case GL_STENCIL_ATTACHMENT:
if (props.stencilAttachment_hasRbo) {
res_info->type = FBO_ATTACHMENT_RENDERBUFFER;
- res_info->rb_format = queryRboFormat(props.stencilAttachment_rbo);
- res_info->rb_multisamples =
- queryRboSamples(
- props.stencilAttachment_rbo);
- res_info->rb_external =
- queryRboEGLImageBacked(
- props.stencilAttachment_rbo);
+ res_info->rb_format = props.stencilAttachment_rbo->format;
+ res_info->rb_multisamples = props.stencilAttachment_rbo->multisamples;
+ 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 {
@@ -2371,21 +2310,16 @@
case GL_DEPTH_STENCIL_ATTACHMENT:
if (props.depthstencilAttachment_hasRbo) {
res_info->type = FBO_ATTACHMENT_RENDERBUFFER;
- res_info->rb_format = queryRboFormat(props.depthstencilAttachment_rbo);
- res_info->rb_multisamples =
- queryRboSamples(
- props.depthstencilAttachment_rbo);
- res_info->rb_external =
- queryRboEGLImageBacked(
- props.depthstencilAttachment_rbo);
+ res_info->rb_format = props.depthstencilAttachment_rbo->format;
+ res_info->rb_multisamples = props.depthstencilAttachment_rbo->multisamples;
+ 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 {
@@ -2506,22 +2440,6 @@
if (framebuffers[i] == mFboState.boundReadFramebuffer) {
bindFramebuffer(GL_READ_FRAMEBUFFER, 0);
}
- // Remove references to all attachments
- auto fboProps = mFboState.fboData.find(framebuffers[i]);
- if (fboProps != mFboState.fboData.end()) {
- for (size_t j = 0; j < fboProps->second.colorAttachmenti_hasRbo.size(); j++) {
- view.unref(fboProps->second.colorAttachmenti_rbos[j]);
- }
- if (fboProps->second.depthAttachment_hasRbo && fboProps->second.depthAttachment_rbo) {
- view.unref(fboProps->second.depthAttachment_rbo);
- }
- if (fboProps->second.stencilAttachment_hasRbo && fboProps->second.stencilAttachment_rbo) {
- view.unref(fboProps->second.stencilAttachment_rbo);
- }
- if (fboProps->second.depthstencilAttachment_hasRbo && fboProps->second.depthstencilAttachment_rbo) {
- view.unref(fboProps->second.depthstencilAttachment_rbo);
- }
- }
mFboState.fboData.erase(framebuffers[i]);
}
}
@@ -2625,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);
@@ -2632,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;
@@ -2640,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;
@@ -2666,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);
@@ -2715,50 +2634,46 @@
boundFboProps(target).completenessDirty = true;
RenderbufferInfo::ScopedView view(mRboState.rboData);
+ auto renderBufferSharedPtr = view.get_shared_ptr(renderbuffer);
if (colorAttachmentIndex != -1) {
if (boundFboProps(target).colorAttachmenti_hasRbo[colorAttachmentIndex] &&
- boundFboProps(target).colorAttachmenti_rbos[colorAttachmentIndex] == renderbuffer) {
- boundFboProps(target).colorAttachmenti_rbos[colorAttachmentIndex] = 0;
+ boundFboProps(target).colorAttachmenti_rbos[colorAttachmentIndex]
+ == renderBufferSharedPtr) {
+ boundFboProps(target).colorAttachmenti_rbos[colorAttachmentIndex] = nullptr;
boundFboProps(target).colorAttachmenti_hasRbo[colorAttachmentIndex] = false;
- view.unref(renderbuffer);
}
}
switch (attachment) {
case GL_DEPTH_ATTACHMENT:
- if (boundFboProps(target).depthAttachment_rbo == renderbuffer &&
+ if (boundFboProps(target).depthAttachment_rbo == renderBufferSharedPtr &&
boundFboProps(target).depthAttachment_hasRbo) {
- boundFboProps(target).depthAttachment_rbo = 0;
+ boundFboProps(target).depthAttachment_rbo = nullptr;
boundFboProps(target).depthAttachment_hasRbo = false;
- view.unref(renderbuffer);
}
break;
case GL_STENCIL_ATTACHMENT:
- if (boundFboProps(target).stencilAttachment_rbo == renderbuffer &&
+ if (boundFboProps(target).stencilAttachment_rbo == renderBufferSharedPtr &&
boundFboProps(target).stencilAttachment_hasRbo) {
- boundFboProps(target).stencilAttachment_rbo = 0;
+ boundFboProps(target).stencilAttachment_rbo = nullptr;
boundFboProps(target).stencilAttachment_hasRbo = false;
- view.unref(renderbuffer);
}
break;
case GL_DEPTH_STENCIL_ATTACHMENT:
- if (boundFboProps(target).depthAttachment_rbo == renderbuffer &&
+ if (boundFboProps(target).depthAttachment_rbo == renderBufferSharedPtr &&
boundFboProps(target).depthAttachment_hasRbo) {
- boundFboProps(target).depthAttachment_rbo = 0;
+ boundFboProps(target).depthAttachment_rbo = nullptr;
boundFboProps(target).depthAttachment_hasRbo = false;
- view.unref(renderbuffer);
}
- if (boundFboProps(target).stencilAttachment_rbo == renderbuffer &&
+ if (boundFboProps(target).stencilAttachment_rbo == renderBufferSharedPtr &&
boundFboProps(target).stencilAttachment_hasRbo) {
- boundFboProps(target).stencilAttachment_rbo = 0;
+ boundFboProps(target).stencilAttachment_rbo = nullptr;
boundFboProps(target).stencilAttachment_hasRbo = false;
- view.unref(renderbuffer);
}
- if (boundFboProps(target).depthstencilAttachment_rbo == renderbuffer &&
+ if (boundFboProps(target).depthstencilAttachment_rbo == renderBufferSharedPtr &&
boundFboProps(target).depthstencilAttachment_hasRbo) {
- boundFboProps(target).depthstencilAttachment_rbo = 0;
+ boundFboProps(target).depthstencilAttachment_rbo = nullptr;
boundFboProps(target).depthstencilAttachment_hasRbo = false;
- view.unref(renderbuffer);
}
break;
}
@@ -2774,74 +2689,61 @@
boundFboProps(target).completenessDirty = true;
RenderbufferInfo::ScopedView view(mRboState.rboData);
+ auto rboSharedPtr = view.get_or_add_shared_ptr(renderbuffer);
if (colorAttachmentIndex != -1) {
- view.unref(boundFboProps(target).colorAttachmenti_rbos[colorAttachmentIndex]);
- view.ref(renderbuffer);
- boundFboProps(target).colorAttachmenti_rbos[colorAttachmentIndex] = renderbuffer;
+ boundFboProps(target).colorAttachmenti_rbos[colorAttachmentIndex] = rboSharedPtr;
boundFboProps(target).colorAttachmenti_hasRbo[colorAttachmentIndex] = attach;
}
switch (attachment) {
case GL_DEPTH_ATTACHMENT:
- view.unref(boundFboProps(target).depthAttachment_rbo);
- view.ref(renderbuffer);
- boundFboProps(target).depthAttachment_rbo = renderbuffer;
+ boundFboProps(target).depthAttachment_rbo = rboSharedPtr;
boundFboProps(target).depthAttachment_hasRbo = attach;
break;
case GL_STENCIL_ATTACHMENT:
- view.unref(boundFboProps(target).stencilAttachment_rbo);
- view.ref(renderbuffer);
- boundFboProps(target).stencilAttachment_rbo = renderbuffer;
+ boundFboProps(target).stencilAttachment_rbo = rboSharedPtr;
boundFboProps(target).stencilAttachment_hasRbo = attach;
break;
case GL_DEPTH_STENCIL_ATTACHMENT:
- view.unref(boundFboProps(target).depthAttachment_rbo);
- view.ref(renderbuffer);
- view.unref(boundFboProps(target).stencilAttachment_rbo);
- view.ref(renderbuffer);
- view.unref(boundFboProps(target).depthstencilAttachment_rbo);
- view.ref(renderbuffer);
- boundFboProps(target).depthAttachment_rbo = renderbuffer;
+ boundFboProps(target).depthAttachment_rbo = rboSharedPtr;
boundFboProps(target).depthAttachment_hasRbo = attach;
- boundFboProps(target).stencilAttachment_rbo = renderbuffer;
+ boundFboProps(target).stencilAttachment_rbo = rboSharedPtr;
boundFboProps(target).stencilAttachment_hasRbo = attach;
- boundFboProps(target).depthstencilAttachment_rbo = renderbuffer;
+ boundFboProps(target).depthstencilAttachment_rbo = rboSharedPtr;
boundFboProps(target).depthstencilAttachment_hasRbo = attach;
break;
}
}
-GLuint GLClientState::getFboAttachmentRboId(GLenum target, GLenum attachment) const {
- GLuint res = 0; // conservative
-
+std::shared_ptr<RboProps> GLClientState::getFboAttachmentRbo(GLenum target, GLenum attachment) const {
int colorAttachmentIndex =
glUtilsColorAttachmentIndex(attachment);
if (colorAttachmentIndex != -1) {
- res = boundFboProps_const(target).colorAttachmenti_rbos[colorAttachmentIndex];
+ return boundFboProps_const(target).colorAttachmenti_rbos[colorAttachmentIndex];
}
switch (attachment) {
case GL_DEPTH_ATTACHMENT:
- res = boundFboProps_const(target).depthAttachment_rbo;
- break;
+ return boundFboProps_const(target).depthAttachment_rbo;
case GL_STENCIL_ATTACHMENT:
- res = boundFboProps_const(target).stencilAttachment_rbo;
- break;
+ return boundFboProps_const(target).stencilAttachment_rbo;
case GL_DEPTH_STENCIL_ATTACHMENT:
- res = boundFboProps_const(target).depthstencilAttachment_rbo;
- break;
+ return boundFboProps_const(target).depthstencilAttachment_rbo;
}
- return res;
+
+ // Bad attachment enum. Should be unreachable.
+ return nullptr;
}
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;
}
@@ -2849,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;
}
@@ -2872,12 +2774,12 @@
}
}
-void GLClientState::setFboCompletenessDirtyForRbo(GLuint rbo) {
+void GLClientState::setFboCompletenessDirtyForRbo(std::shared_ptr<RboProps> rbo) {
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 (props.colorAttachmenti_hasRbo[i]) {
if (rbo == props.colorAttachmenti_rbos[i]) {
props.completenessDirty = true;
return;
@@ -2885,14 +2787,14 @@
}
}
- if (props.depthAttachment_hasTexObj) {
+ if (props.depthAttachment_hasRbo) {
if (rbo == props.depthAttachment_rbo) {
props.completenessDirty = true;
return;
}
}
- if (props.stencilAttachment_hasTexObj) {
+ if (props.stencilAttachment_hasRbo) {
if (rbo == props.stencilAttachment_rbo) {
props.completenessDirty = true;
return;
@@ -2937,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];
- } 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;
- } 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;
- } 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;
- } 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) {
@@ -3056,6 +2928,11 @@
void GLClientState::setRenderbufferInfo(RenderbufferInfo* rbInfo) {
mRboState.rboData = rbInfo;
+ if (rbInfo) {
+ RenderbufferInfo::ScopedView view(mRboState.rboData);
+ auto rbo = view.get_or_add_shared_ptr(0);
+ mRboState.boundRenderbuffer = rbo;
+ }
}
void GLClientState::setSamplerInfo(SamplerInfo* samplerInfo) {
@@ -3072,6 +2949,19 @@
void GLClientState::fromMakeCurrent() {
if (mFboState.fboData.find(0) == mFboState.fboData.end()) {
addFreshFramebuffer(0);
+ FboProps& default_fb_props = mFboState.fboData[0];
+ default_fb_props.colorAttachmenti_hasRbo[0] = true;
+ default_fb_props.depthAttachment_hasRbo = true;
+ default_fb_props.stencilAttachment_hasRbo = true;
+ default_fb_props.depthstencilAttachment_hasRbo = true;
+ RenderbufferInfo::ScopedView view(mRboState.rboData);
+ // Use RBO 0 as placeholder
+ auto rbo0 = view.get_or_add_shared_ptr(0);
+ default_fb_props.colorAttachmenti_rbos[0] = rbo0;
+ default_fb_props.depthAttachment_rbo = rbo0;
+ default_fb_props.stencilAttachment_rbo = rbo0;
+ default_fb_props.depthstencilAttachment_rbo = rbo0;
+
}
if (!samplerExists(0)) {
@@ -3079,11 +2969,6 @@
setExistence(ObjectType::Sampler, true, 1, &id);
}
- FboProps& default_fb_props = mFboState.fboData[0];
- default_fb_props.colorAttachmenti_hasRbo[0] = true;
- default_fb_props.depthAttachment_hasRbo = true;
- default_fb_props.stencilAttachment_hasRbo = true;
- default_fb_props.depthstencilAttachment_hasRbo = true;
}
void GLClientState::initFromCaps(
diff --git a/shared/OpenglCodecCommon/GLClientState.h b/shared/OpenglCodecCommon/GLClientState.h
index a9da8d0..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,19 +91,19 @@
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;
bool stencilAttachment_hasTexObj;
bool depthstencilAttachment_hasTexObj;
- std::vector<GLuint> colorAttachmenti_rbos;
- GLuint depthAttachment_rbo = 0;
- GLuint stencilAttachment_rbo = 0;
- GLuint depthstencilAttachment_rbo = 0;
+ std::vector<std::shared_ptr<RboProps>> colorAttachmenti_rbos;
+ std::shared_ptr<RboProps> depthAttachment_rbo = 0;
+ std::shared_ptr<RboProps> stencilAttachment_rbo = 0;
+ std::shared_ptr<RboProps> depthstencilAttachment_rbo = 0;
std::vector<bool> colorAttachmenti_hasRbo;
bool depthAttachment_hasRbo = false;
@@ -489,21 +490,21 @@
// 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);
void detachRboFromFbo(GLenum target, GLenum attachment, GLuint renderbuffer);
void attachRbo(GLenum target, GLenum attachment, GLuint renderbuffer);
- GLuint getFboAttachmentRboId(GLenum target, GLenum attachment) const;
+ std::shared_ptr<RboProps> getFboAttachmentRbo(GLenum target, GLenum attachment) const;
// 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);
- void setFboCompletenessDirtyForRbo(GLuint rbo_name);
+ void setFboCompletenessDirtyForRbo(std::shared_ptr<RboProps> rbo);
// Transform feedback state
void setTransformFeedbackActive(bool active);
@@ -712,7 +713,7 @@
GLenum internalformat);
struct RboState {
- GLuint boundRenderbuffer;
+ std::shared_ptr<RboProps> boundRenderbuffer;
// Connects to share group.
// Expected that share group lifetime outlives this context.
RenderbufferInfo* rboData;
@@ -734,18 +735,14 @@
const FboProps& boundFboProps_const(GLenum target) const;
// Querying framebuffer format
- GLenum queryRboFormat(GLuint name) const;
- GLsizei queryRboSamples(GLuint name) const;
- GLsizei queryRboWidth(GLuint name) const;
- GLsizei queryRboHeight(GLuint name) const;
- bool queryRboEGLImageBacked(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;
- 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/StateTrackingSupport.h b/shared/OpenglCodecCommon/StateTrackingSupport.h
index 7a009d8..6ed8460 100644
--- a/shared/OpenglCodecCommon/StateTrackingSupport.h
+++ b/shared/OpenglCodecCommon/StateTrackingSupport.h
@@ -20,6 +20,7 @@
#include "android/base/synchronization/AndroidLock.h"
#include <GLES2/gl2.h>
+#include <memory>
template <class IndexType, bool initialIsTrue>
class PredicateMap {
@@ -104,8 +105,8 @@
GLsizei width;
GLsizei height;
bool previouslyBound;
- uint32_t refcount;
bool boundEGLImage;
+ GLuint id;
};
struct SamplerProps {
@@ -130,7 +131,7 @@
struct RenderbufferInfo {
android::base::guest::Lock infoLock;
- android::base::HybridComponentManager<1000, uint32_t, RboProps> component;
+ android::base::HybridComponentManager<1000, uint32_t, std::shared_ptr<RboProps>> component;
void lock() { infoLock.lock(); }
void unlock() { infoLock.unlock(); }
@@ -139,62 +140,63 @@
public:
ScopedView(RenderbufferInfo* info) : ScopedLockedView<RenderbufferInfo>(info) { }
bool hasRbo(GLuint id) const {
- const RboProps* info = internalInfo_const()->component.get_const(id);
- if (!info) return false;
- return 0 != info->refcount;
+ return nullptr != internalInfo_const()->component.get_const(id);
}
virtual ~ScopedView() = default;
RboProps* get(GLuint id) {
- return internalInfo()->component.get(id);
+ auto rboPropPtr = internalInfo()->component.get(id);
+ if (!rboPropPtr) {
+ return nullptr;
+ }
+ return rboPropPtr->get();
+ }
+ std::shared_ptr<RboProps> get_or_add_shared_ptr(GLuint id) {
+ auto rboPropPtr = internalInfo()->component.get(id);
+ if (!rboPropPtr) {
+ addFresh(id);
+ rboPropPtr = internalInfo()->component.get(id);
+ }
+ return *rboPropPtr;
+ }
+ std::shared_ptr<RboProps> get_shared_ptr(GLuint id) {
+ auto rboPropPtr = internalInfo()->component.get(id);
+ if (!internalInfo()->component.get(id)) {
+ return nullptr;
+ }
+ return *rboPropPtr;
}
const RboProps* get_const(GLuint id) {
- return internalInfo_const()->component.get_const(id);
+ auto rboPropPtr = internalInfo()->component.get_const(id);
+ if (!rboPropPtr) {
+ return nullptr;
+ }
+ return rboPropPtr->get();
}
void addFresh(GLuint id) {
- RboProps props;
- props.format = GL_NONE;
- props.multisamples = 0;
- props.width = 0;
- props.height = 0;
- props.previouslyBound = false;
- props.refcount = 1;
- props.boundEGLImage = false;
- internalInfo()->component.add(id, props);
+ std::shared_ptr<RboProps> props(new RboProps());
+ props->format = GL_NONE;
+ props->multisamples = 0;
+ props->width = 0;
+ props->height = 0;
+ props->previouslyBound = false;
+ props->boundEGLImage = false;
+ props->id = id;
+ internalInfo()->component.add(id, std::move(props));
}
- RboProps* bind(GLuint id) {
- if (!hasRbo(id)) addFresh(id);
- ref(id);
- RboProps* res = get(id);
+ std::shared_ptr<RboProps> bind(GLuint id) {
+ auto res = get_shared_ptr(id);
+ if (!res) {
+ addFresh(id);
+ res = get_shared_ptr(id);
+ }
res->previouslyBound = true;
return res;
}
- void ref(GLuint id) {
+ void remove(GLuint id) {
if (id == 0) {
return;
}
- if (!hasRbo(id)) addFresh(id);
- RboProps* props = get(id);
- if (!props) return;
- ++props->refcount;
- }
- bool unref(GLuint id) {
- if (id == 0) {
- return false;
- }
- RboProps* props = get(id);
- if (!props) return false;
- if (!props->refcount) return false;
- --props->refcount;
- bool gone = 0 == props->refcount;
- if (gone) {
- props->format = 0;
- props->multisamples = 0;
- props->width = 0;
- props->height = 0;
- props->previouslyBound = false;
- props->boundEGLImage = false;
- }
- return gone;
+ internalInfo()->component.remove(id);
}
};
};
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 ||
diff --git a/system/OpenglSystemCommon/HostConnection.cpp b/system/OpenglSystemCommon/HostConnection.cpp
index ac7ef15..9d41be4 100644
--- a/system/OpenglSystemCommon/HostConnection.cpp
+++ b/system/OpenglSystemCommon/HostConnection.cpp
@@ -745,7 +745,8 @@
queryAndSetHWCMultiConfigs(rcEnc);
queryVersion(rcEnc);
if (m_processPipe) {
- m_processPipe->processPipeInit(m_rendernodeFd, m_connectionType, rcEnc);
+ auto fd = (m_connectionType == HOST_CONNECTION_VIRTIO_GPU_ADDRESS_SPACE) ? m_rendernodeFd : -1;
+ m_processPipe->processPipeInit(fd, m_connectionType, rcEnc);
}
}
return m_rcEnc.get();
diff --git a/system/codecs/c2/decoders/avcdec/Android.bp b/system/codecs/c2/decoders/avcdec/Android.bp
index 78ffd82..5d840b0 100644
--- a/system/codecs/c2/decoders/avcdec/Android.bp
+++ b/system/codecs/c2/decoders/avcdec/Android.bp
@@ -15,6 +15,7 @@
],
srcs: ["C2GoldfishAvcDec.cpp",
+ "GoldfishH264Helper.cpp",
"MediaH264Decoder.cpp",
],
@@ -27,4 +28,7 @@
header_libs: [
"libgralloc_cb.ranchu",
],
+
+ static_libs: ["libavcdec",
+ ],
}
diff --git a/system/codecs/c2/decoders/avcdec/C2GoldfishAvcDec.cpp b/system/codecs/c2/decoders/avcdec/C2GoldfishAvcDec.cpp
index 93bd079..90b5653 100644
--- a/system/codecs/c2/decoders/avcdec/C2GoldfishAvcDec.cpp
+++ b/system/codecs/c2/decoders/avcdec/C2GoldfishAvcDec.cpp
@@ -670,31 +670,14 @@
void C2GoldfishAvcDec::checkMode(const std::shared_ptr<C2BlockPool> &pool) {
mWidth = mIntf->width();
mHeight = mIntf->height();
- {
- // now get the block
- constexpr uint32_t format = HAL_PIXEL_FORMAT_YCBCR_420_888;
- std::shared_ptr<C2GraphicBlock> block;
- C2MemoryUsage usage = {C2MemoryUsage::CPU_READ,
- C2MemoryUsage::CPU_WRITE};
- usage.expected = (uint64_t)(BufferUsage::VIDEO_DECODER);
-
- c2_status_t err = pool->fetchGraphicBlock(align(mWidth, 16), mHeight,
- format, usage, &block);
- if (err != C2_OK) {
- ALOGE("fetchGraphicBlock for Output failed with status %d", err);
- return;
- }
- auto c2Handle = block->handle();
- native_handle_t *grallocHandle =
- UnwrapNativeCodec2GrallocHandle(c2Handle);
- int hostColorBufferId = getColorBufferHandle(grallocHandle);
- if (hostColorBufferId > 0) {
- DDD("decoding to host color buffer");
- mEnableAndroidNativeBuffers = true;
- } else {
- DDD("decoding to guest byte buffer");
- mEnableAndroidNativeBuffers = false;
- }
+ const bool isGraphic = (pool->getAllocatorId() & C2Allocator::GRAPHIC);
+ DDD("buffer id %d", (int)(pool->getAllocatorId()));
+ if (isGraphic) {
+ DDD("decoding to host color buffer");
+ mEnableAndroidNativeBuffers = true;
+ } else {
+ DDD("decoding to guest byte buffer");
+ mEnableAndroidNativeBuffers = false;
}
}
@@ -894,11 +877,6 @@
return;
}
- if (false == mHeaderDecoded) {
- /* Decode header and get dimensions */
- setParams(mStride);
- }
-
DDD("flag is %x", work->input.flags);
if (work->input.flags & C2FrameData::FLAG_CODEC_CONFIG) {
hasPicture = false;
@@ -913,9 +891,50 @@
removePts(mPts);
}
+ bool whChanged = false;
+ if (GoldfishH264Helper::isSpsFrame(mInPBuffer, mInPBufferSize)) {
+ mH264Helper.reset(new GoldfishH264Helper(mWidth, mHeight));
+ whChanged = mH264Helper->decodeHeader(mInPBuffer, mInPBufferSize);
+ if (whChanged) {
+ DDD("w changed from old %d to new %d\n", mWidth, mH264Helper->getWidth());
+ DDD("h changed from old %d to new %d\n", mHeight, mH264Helper->getHeight());
+ if (1) {
+ drainInternal(DRAIN_COMPONENT_NO_EOS, pool, work);
+ resetDecoder();
+ resetPlugin();
+ work->workletsProcessed = 0u;
+ }
+ {
+ mWidth = mH264Helper->getWidth();
+ mHeight = mH264Helper->getHeight();
+ C2StreamPictureSizeInfo::output size(0u, mWidth, mHeight);
+ std::vector<std::unique_ptr<C2SettingResult>> failures;
+ c2_status_t err = mIntf->config({&size}, C2_MAY_BLOCK, &failures);
+ if (err == OK) {
+ work->worklets.front()->output.configUpdate.push_back(
+ C2Param::Copy(size));
+ ensureDecoderState(pool);
+ } else {
+ ALOGE("Cannot set width and height");
+ mSignalledError = true;
+ work->workletsProcessed = 1u;
+ work->result = C2_CORRUPTED;
+ return;
+ }
+ }
+ if (!mContext) {
+ DDD("creating decoder context to host in process work");
+ checkMode(pool);
+ createDecoder();
+ }
+ continue;
+ } // end of whChanged
+ } // end of isSpsFrame
+
uint32_t delay;
GETTIME(&mTimeStart, nullptr);
TIME_DIFF(mTimeEnd, mTimeStart, delay);
+ (void)delay;
//(void) ivdec_api_function(mDecHandle, &s_decode_ip, &s_decode_op);
DDD("decoding");
h264_result_t h264Res =
@@ -932,44 +951,10 @@
uint32_t decodeTime;
GETTIME(&mTimeEnd, nullptr);
TIME_DIFF(mTimeStart, mTimeEnd, decodeTime);
+ (void)decodeTime;
}
- // TODO: handle res change
- if (0) {
- DDD("resolution changed");
- drainInternal(DRAIN_COMPONENT_NO_EOS, pool, work);
- resetDecoder();
- resetPlugin();
- work->workletsProcessed = 0u;
- /* Decode header and get new dimensions */
- setParams(mStride);
- // (void) ivdec_api_function(mDecHandle, &s_decode_ip,
- // &s_decode_op);
- }
if (mImg.data != nullptr) {
- // check for new width and height
- auto decodedW = mImg.width;
- auto decodedH = mImg.height;
- if (decodedW != mWidth || decodedH != mHeight) {
- mWidth = decodedW;
- mHeight = decodedH;
-
- C2StreamPictureSizeInfo::output size(0u, mWidth, mHeight);
- std::vector<std::unique_ptr<C2SettingResult>> failures;
- c2_status_t err = mIntf->config({&size}, C2_MAY_BLOCK, &failures);
- if (err == OK) {
- work->worklets.front()->output.configUpdate.push_back(
- C2Param::Copy(size));
- ensureDecoderState(pool);
- } else {
- ALOGE("Cannot set width and height");
- mSignalledError = true;
- work->workletsProcessed = 1u;
- work->result = C2_CORRUPTED;
- return;
- }
- }
-
DDD("got data %" PRIu64 " with pts %" PRIu64, getWorkIndex(mImg.pts), mImg.pts);
mHeaderDecoded = true;
copyImageData(mImg);
diff --git a/system/codecs/c2/decoders/avcdec/C2GoldfishAvcDec.h b/system/codecs/c2/decoders/avcdec/C2GoldfishAvcDec.h
index 914a10e..afa27f5 100644
--- a/system/codecs/c2/decoders/avcdec/C2GoldfishAvcDec.h
+++ b/system/codecs/c2/decoders/avcdec/C2GoldfishAvcDec.h
@@ -22,6 +22,7 @@
#include <media/stagefright/foundation/ColorUtils.h>
#include "MediaH264Decoder.h"
+#include "GoldfishH264Helper.h"
#include <SimpleC2Component.h>
#include <atomic>
#include <map>
@@ -152,6 +153,8 @@
std::vector<uint8_t> mCsd1;
void decodeHeaderAfterFlush();
+ std::unique_ptr<GoldfishH264Helper> mH264Helper;
+
C2_DO_NOT_COPY(C2GoldfishAvcDec);
};
diff --git a/system/codecs/c2/decoders/avcdec/GoldfishH264Helper.cpp b/system/codecs/c2/decoders/avcdec/GoldfishH264Helper.cpp
new file mode 100644
index 0000000..077ef15
--- /dev/null
+++ b/system/codecs/c2/decoders/avcdec/GoldfishH264Helper.cpp
@@ -0,0 +1,311 @@
+/*
+ * Copyright 2022 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.
+ */
+
+#include "GoldfishH264Helper.h"
+
+#define LOG_TAG "GoldfishH264Helper"
+#include <log/log.h>
+
+
+#define DEBUG 0
+#if DEBUG
+#define DDD(...) ALOGD(__VA_ARGS__)
+#else
+#define DDD(...) ((void)0)
+#endif
+
+
+#include <Codec2Mapper.h>
+
+#define ivdec_api_function ih264d_api_function
+#define ivdext_create_ip_t ih264d_create_ip_t
+#define ivdext_create_op_t ih264d_create_op_t
+#define ivdext_delete_ip_t ih264d_delete_ip_t
+#define ivdext_delete_op_t ih264d_delete_op_t
+#define ivdext_ctl_set_num_cores_ip_t ih264d_ctl_set_num_cores_ip_t
+#define ivdext_ctl_set_num_cores_op_t ih264d_ctl_set_num_cores_op_t
+#define ivdext_ctl_get_vui_params_ip_t ih264d_ctl_get_vui_params_ip_t
+#define ivdext_ctl_get_vui_params_op_t ih264d_ctl_get_vui_params_op_t
+#define ALIGN128(x) ((((x) + 127) >> 7) << 7)
+#define MAX_NUM_CORES 4
+#define IVDEXT_CMD_CTL_SET_NUM_CORES \
+ (IVD_CONTROL_API_COMMAND_TYPE_T)IH264D_CMD_CTL_SET_NUM_CORES
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+
+namespace android {
+
+static void *ivd_aligned_malloc(void *ctxt, WORD32 alignment, WORD32 size) {
+ (void) ctxt;
+ return memalign(alignment, size);
+}
+
+static void ivd_aligned_free(void *ctxt, void *mem) {
+ (void) ctxt;
+ free(mem);
+}
+
+
+GoldfishH264Helper::GoldfishH264Helper(int w, int h):mWidth(w),mHeight(h) { createDecoder(); }
+
+GoldfishH264Helper::~GoldfishH264Helper() {
+ destroyDecoder();
+}
+
+void GoldfishH264Helper::createDecoder() {
+ ivdext_create_ip_t s_create_ip = {};
+ ivdext_create_op_t s_create_op = {};
+
+ s_create_ip.s_ivd_create_ip_t.u4_size = sizeof(ivdext_create_ip_t);
+ s_create_ip.s_ivd_create_ip_t.e_cmd = IVD_CMD_CREATE;
+ s_create_ip.s_ivd_create_ip_t.u4_share_disp_buf = 0;
+ s_create_ip.s_ivd_create_ip_t.e_output_format = mIvColorformat;
+ s_create_ip.s_ivd_create_ip_t.pf_aligned_alloc = ivd_aligned_malloc;
+ s_create_ip.s_ivd_create_ip_t.pf_aligned_free = ivd_aligned_free;
+ s_create_ip.s_ivd_create_ip_t.pv_mem_ctxt = nullptr;
+ s_create_op.s_ivd_create_op_t.u4_size = sizeof(ivdext_create_op_t);
+ IV_API_CALL_STATUS_T status =
+ ivdec_api_function(mDecHandle, &s_create_ip, &s_create_op);
+ if (status != IV_SUCCESS) {
+ ALOGE("error in %s: 0x%x", __func__,
+ s_create_op.s_ivd_create_op_t.u4_error_code);
+ return;
+ }
+ mDecHandle = (iv_obj_t *)s_create_op.s_ivd_create_op_t.pv_handle;
+ mDecHandle->pv_fxns = (void *)ivdec_api_function;
+ mDecHandle->u4_size = sizeof(iv_obj_t);
+
+ mStride = ALIGN128(mWidth);
+
+ setNumCores();
+}
+
+void GoldfishH264Helper::destroyDecoder() {
+ if (mDecHandle) {
+ ivdext_delete_ip_t s_delete_ip = {};
+ ivdext_delete_op_t s_delete_op = {};
+
+ s_delete_ip.s_ivd_delete_ip_t.u4_size = sizeof(ivdext_delete_ip_t);
+ s_delete_ip.s_ivd_delete_ip_t.e_cmd = IVD_CMD_DELETE;
+ s_delete_op.s_ivd_delete_op_t.u4_size = sizeof(ivdext_delete_op_t);
+ IV_API_CALL_STATUS_T status =
+ ivdec_api_function(mDecHandle, &s_delete_ip, &s_delete_op);
+ if (status != IV_SUCCESS) {
+ ALOGE("error in %s: 0x%x", __func__,
+ s_delete_op.s_ivd_delete_op_t.u4_error_code);
+ }
+ mDecHandle = nullptr;
+ }
+}
+
+void GoldfishH264Helper::setNumCores() {
+ ivdext_ctl_set_num_cores_ip_t s_set_num_cores_ip = {};
+ ivdext_ctl_set_num_cores_op_t s_set_num_cores_op = {};
+
+ s_set_num_cores_ip.u4_size = sizeof(ivdext_ctl_set_num_cores_ip_t);
+ s_set_num_cores_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_set_num_cores_ip.e_sub_cmd = IVDEXT_CMD_CTL_SET_NUM_CORES;
+ s_set_num_cores_ip.u4_num_cores = mNumCores;
+ s_set_num_cores_op.u4_size = sizeof(ivdext_ctl_set_num_cores_op_t);
+ IV_API_CALL_STATUS_T status = ivdec_api_function(
+ mDecHandle, &s_set_num_cores_ip, &s_set_num_cores_op);
+ if (IV_SUCCESS != status) {
+ DDD("error in %s: 0x%x", __func__, s_set_num_cores_op.u4_error_code);
+ }
+}
+
+void GoldfishH264Helper::resetDecoder() {
+ ivd_ctl_reset_ip_t s_reset_ip = {};
+ ivd_ctl_reset_op_t s_reset_op = {};
+
+ s_reset_ip.u4_size = sizeof(ivd_ctl_reset_ip_t);
+ s_reset_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_reset_ip.e_sub_cmd = IVD_CMD_CTL_RESET;
+ s_reset_op.u4_size = sizeof(ivd_ctl_reset_op_t);
+ IV_API_CALL_STATUS_T status =
+ ivdec_api_function(mDecHandle, &s_reset_ip, &s_reset_op);
+ if (IV_SUCCESS != status) {
+ ALOGE("error in %s: 0x%x", __func__, s_reset_op.u4_error_code);
+ }
+ setNumCores();
+}
+
+void GoldfishH264Helper::setParams(size_t stride,
+ IVD_VIDEO_DECODE_MODE_T dec_mode) {
+ ih264d_ctl_set_config_ip_t s_h264d_set_dyn_params_ip = {};
+ ih264d_ctl_set_config_op_t s_h264d_set_dyn_params_op = {};
+ ivd_ctl_set_config_ip_t *ps_set_dyn_params_ip =
+ &s_h264d_set_dyn_params_ip.s_ivd_ctl_set_config_ip_t;
+ ivd_ctl_set_config_op_t *ps_set_dyn_params_op =
+ &s_h264d_set_dyn_params_op.s_ivd_ctl_set_config_op_t;
+
+ ps_set_dyn_params_ip->u4_size = sizeof(ih264d_ctl_set_config_ip_t);
+ ps_set_dyn_params_ip->e_cmd = IVD_CMD_VIDEO_CTL;
+ ps_set_dyn_params_ip->e_sub_cmd = IVD_CMD_CTL_SETPARAMS;
+ ps_set_dyn_params_ip->u4_disp_wd = (UWORD32) stride;
+ ps_set_dyn_params_ip->e_frm_skip_mode = IVD_SKIP_NONE;
+ ps_set_dyn_params_ip->e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
+ ps_set_dyn_params_ip->e_vid_dec_mode = dec_mode;
+ ps_set_dyn_params_op->u4_size = sizeof(ih264d_ctl_set_config_op_t);
+ IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
+ &s_h264d_set_dyn_params_ip,
+ &s_h264d_set_dyn_params_op);
+ if (status != IV_SUCCESS) {
+ ALOGE("error in %s: 0x%x", __func__,
+ ps_set_dyn_params_op->u4_error_code);
+ }
+}
+
+bool GoldfishH264Helper::isSpsFrame(const uint8_t* frame, int inSize) {
+ if (inSize < 5) return false;
+ if (frame[0] == 0 && frame[1] == 0 && frame[2] == 0 && frame[3] == 1) {
+ const bool forbiddenBitIsInvalid = 0x80 & frame[4];
+ if (forbiddenBitIsInvalid) {
+ return false;
+ }
+ // nalu type is the lower 5 bits
+ uint8_t naluType = 0x1f & frame[4];
+ if (naluType == 7
+ || naluType == 8
+ ) return true;
+ else return false;
+ } else {
+ return false;
+ }
+}
+
+bool GoldfishH264Helper::decodeHeader(const uint8_t *frame, int inSize) {
+ // should we check the header for vps/sps/pps frame ? otherwise
+ // there is no point calling decoder
+ if (!isSpsFrame(frame, inSize)) {
+ DDD("could not find valid vps frame");
+ return false;
+ } else {
+ DDD("found valid vps frame");
+ }
+
+ ih264d_video_decode_ip_t s_h264d_decode_ip = {};
+ ih264d_video_decode_op_t s_h264d_decode_op = {};
+ ivd_video_decode_ip_t *ps_decode_ip = &s_h264d_decode_ip.s_ivd_video_decode_ip_t;
+ ivd_video_decode_op_t *ps_decode_op = &s_h264d_decode_op.s_ivd_video_decode_op_t;
+
+ // setup input/output arguments to decoder
+ setDecodeArgs(ps_decode_ip, ps_decode_op, frame, mStride,
+ 0, // offset
+ inSize, // size
+ 0 // time-stamp, does not matter
+ );
+
+ setParams(mStride, IVD_DECODE_HEADER);
+
+ // now kick off the decoding
+ IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle, ps_decode_ip, ps_decode_op);
+ if (status != IV_SUCCESS) {
+ ALOGE("failed to call decoder function for header\n");
+ ALOGE("error in %s: 0x%x", __func__,
+ ps_decode_op->u4_error_code);
+ }
+
+ if (IVD_RES_CHANGED == (ps_decode_op->u4_error_code & IVD_ERROR_MASK)) {
+ DDD("resolution changed, reset decoder");
+ resetDecoder();
+ setParams(mStride, IVD_DECODE_HEADER);
+ ivdec_api_function(mDecHandle, ps_decode_ip, ps_decode_op);
+ }
+
+ // get the w/h and update
+ if (0 < ps_decode_op->u4_pic_wd && 0 < ps_decode_op->u4_pic_ht) {
+ DDD("success decode w/h %d %d", ps_decode_op->u4_pic_wd , ps_decode_op->u4_pic_ht);
+ DDD("existing w/h %d %d", mWidth, mHeight);
+ if (ps_decode_op->u4_pic_wd != mWidth || ps_decode_op->u4_pic_ht != mHeight) {
+ mWidth = ps_decode_op->u4_pic_wd;
+ mHeight = ps_decode_op->u4_pic_ht;
+ return true;
+ } else {
+ DDD("success decode w/h, but they are the same %d %d", ps_decode_op->u4_pic_wd , ps_decode_op->u4_pic_ht);
+ }
+ } else {
+ ALOGE("could not decode w/h");
+ }
+
+ // get output delay
+ if (ps_decode_op->i4_reorder_depth >= 0) {
+ if (mOutputDelay != ps_decode_op->i4_reorder_depth) {
+ mOutputDelay = ps_decode_op->i4_reorder_depth;
+ DDD("New Output delay %d ", mOutputDelay);
+ } else {
+ DDD("same Output delay %d ", mOutputDelay);
+ }
+ }
+
+ return false;
+}
+
+bool GoldfishH264Helper::setDecodeArgs(ivd_video_decode_ip_t *ps_decode_ip,
+ ivd_video_decode_op_t *ps_decode_op,
+ const uint8_t *inBuffer,
+ uint32_t displayStride, size_t inOffset,
+ size_t inSize, uint32_t tsMarker) {
+ uint32_t displayHeight = mHeight;
+ size_t lumaSize = displayStride * displayHeight;
+ size_t chromaSize = lumaSize >> 2;
+
+ if (mStride != displayStride) {
+ mStride = displayStride;
+ }
+
+ // force decoder to always decode header and get dimensions,
+ // hope this will be quick and cheap
+ setParams(mStride, IVD_DECODE_HEADER);
+
+ ps_decode_ip->u4_size = sizeof(ih264d_video_decode_ip_t);
+ ps_decode_ip->e_cmd = IVD_CMD_VIDEO_DECODE;
+ if (inBuffer) {
+ ps_decode_ip->u4_ts = tsMarker;
+ ps_decode_ip->pv_stream_buffer = const_cast<uint8_t *>(inBuffer) + inOffset;
+ ps_decode_ip->u4_num_Bytes = inSize;
+ } else {
+ ps_decode_ip->u4_ts = 0;
+ ps_decode_ip->pv_stream_buffer = nullptr;
+ ps_decode_ip->u4_num_Bytes = 0;
+ }
+ DDD("setting pv_stream_buffer 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
+ ((uint8_t*)(ps_decode_ip->pv_stream_buffer))[0],
+ ((uint8_t*)(ps_decode_ip->pv_stream_buffer))[1],
+ ((uint8_t*)(ps_decode_ip->pv_stream_buffer))[2],
+ ((uint8_t*)(ps_decode_ip->pv_stream_buffer))[3],
+ ((uint8_t*)(ps_decode_ip->pv_stream_buffer))[4],
+ ((uint8_t*)(ps_decode_ip->pv_stream_buffer))[5],
+ ((uint8_t*)(ps_decode_ip->pv_stream_buffer))[6],
+ ((uint8_t*)(ps_decode_ip->pv_stream_buffer))[7]
+ );
+ DDD("input bytes %d", ps_decode_ip->u4_num_Bytes);
+
+ ps_decode_ip->s_out_buffer.u4_min_out_buf_size[0] = lumaSize;
+ ps_decode_ip->s_out_buffer.u4_min_out_buf_size[1] = chromaSize;
+ ps_decode_ip->s_out_buffer.u4_min_out_buf_size[2] = chromaSize;
+ {
+ ps_decode_ip->s_out_buffer.pu1_bufs[0] = nullptr;
+ ps_decode_ip->s_out_buffer.pu1_bufs[1] = nullptr;
+ ps_decode_ip->s_out_buffer.pu1_bufs[2] = nullptr;
+ }
+ ps_decode_ip->s_out_buffer.u4_num_bufs = 3;
+ ps_decode_op->u4_size = sizeof(ih264d_video_decode_op_t);
+ ps_decode_op->u4_output_present = 0;
+
+ return true;
+}
+
+} // namespace android
diff --git a/system/codecs/c2/decoders/avcdec/GoldfishH264Helper.h b/system/codecs/c2/decoders/avcdec/GoldfishH264Helper.h
new file mode 100644
index 0000000..ec3b384
--- /dev/null
+++ b/system/codecs/c2/decoders/avcdec/GoldfishH264Helper.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2022 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 GOLDFISH_H264_HELPER_H_
+#define GOLDFISH_H264_HELPER_H_
+
+#include <inttypes.h>
+#include "ih264_typedefs.h"
+#include "ih264d.h"
+
+
+namespace android {
+
+// this class is just to provide some functions to decode header
+// so that we know w/h of each sps
+class GoldfishH264Helper {
+ public:
+ GoldfishH264Helper(int w, int h);
+ ~GoldfishH264Helper();
+
+ // check whether the frame is sps; typical h264 will have
+ // a frame that is sps/pps together
+ static bool isSpsFrame(const uint8_t* frame, int inSize);
+ public:
+ // return true if decoding finds out w/h changed;
+ // otherwise false
+ bool decodeHeader(const uint8_t *frame, int inSize);
+ int getWidth() const { return mWidth; }
+ int getHeight() const { return mHeight; }
+
+ private:
+ void createDecoder();
+ void destroyDecoder();
+ void resetDecoder();
+ void setNumCores();
+ void setParams(size_t stride, IVD_VIDEO_DECODE_MODE_T dec_mode);
+ bool setDecodeArgs(ivd_video_decode_ip_t *ps_decode_ip,
+ ivd_video_decode_op_t *ps_decode_op,
+ const uint8_t *inBuffer, uint32_t displayStride,
+ size_t inOffset, size_t inSize, uint32_t tsMarker);
+
+ private:
+ iv_obj_t *mDecHandle = nullptr;
+ int mWidth = 320;
+ int mHeight = 240;
+ int mNumCores = 1;
+ int mStride = 16;
+ int mOutputDelay = 8; // default
+ IV_COLOR_FORMAT_T mIvColorformat = IV_YUV_420P;
+};
+
+} // namespace android
+#endif
diff --git a/system/codecs/c2/decoders/hevcdec/Android.bp b/system/codecs/c2/decoders/hevcdec/Android.bp
index fddd276..f1b9c82 100644
--- a/system/codecs/c2/decoders/hevcdec/Android.bp
+++ b/system/codecs/c2/decoders/hevcdec/Android.bp
@@ -15,6 +15,7 @@
],
srcs: ["C2GoldfishHevcDec.cpp",
+ "GoldfishHevcHelper.cpp",
"MediaHevcDecoder.cpp",
],
@@ -28,5 +29,8 @@
"libgralloc_cb.ranchu",
],
+ static_libs: ["libhevcdec",
+ ],
+
}
diff --git a/system/codecs/c2/decoders/hevcdec/C2GoldfishHevcDec.cpp b/system/codecs/c2/decoders/hevcdec/C2GoldfishHevcDec.cpp
index 51934d5..7008bd5 100644
--- a/system/codecs/c2/decoders/hevcdec/C2GoldfishHevcDec.cpp
+++ b/system/codecs/c2/decoders/hevcdec/C2GoldfishHevcDec.cpp
@@ -457,6 +457,7 @@
}
mContext->initHevcContext(mWidth, mHeight, mWidth, mHeight,
MediaHevcDecoder::PixelFormat::YUV420P);
+
return OK;
}
@@ -660,31 +661,14 @@
void C2GoldfishHevcDec::checkMode(const std::shared_ptr<C2BlockPool> &pool) {
mWidth = mIntf->width();
mHeight = mIntf->height();
- {
- // now get the block
- constexpr uint32_t format = HAL_PIXEL_FORMAT_YCBCR_420_888;
- std::shared_ptr<C2GraphicBlock> block;
- C2MemoryUsage usage = {C2MemoryUsage::CPU_READ,
- C2MemoryUsage::CPU_WRITE};
- usage.expected = (uint64_t)(BufferUsage::VIDEO_DECODER);
-
- c2_status_t err = pool->fetchGraphicBlock(align(mWidth, 16), mHeight,
- format, usage, &block);
- if (err != C2_OK) {
- ALOGE("fetchGraphicBlock for Output failed with status %d", err);
- return;
- }
- auto c2Handle = block->handle();
- native_handle_t *grallocHandle =
- UnwrapNativeCodec2GrallocHandle(c2Handle);
- int hostColorBufferId = getColorBufferHandle(grallocHandle);
- if (hostColorBufferId > 0) {
- DDD("decoding to host color buffer");
- mEnableAndroidNativeBuffers = true;
- } else {
- DDD("decoding to guest byte buffer");
- mEnableAndroidNativeBuffers = false;
- }
+ const bool isGraphic = (pool->getAllocatorId() & C2Allocator::GRAPHIC);
+ DDD("buffer id %d", (int)(pool->getAllocatorId()));
+ if (isGraphic) {
+ DDD("decoding to host color buffer");
+ mEnableAndroidNativeBuffers = true;
+ } else {
+ DDD("decoding to guest byte buffer");
+ mEnableAndroidNativeBuffers = false;
}
}
@@ -884,11 +868,6 @@
return;
}
- if (false == mHeaderDecoded) {
- /* Decode header and get dimensions */
- setParams(mStride);
- }
-
DDD("flag is %x", work->input.flags);
if (work->input.flags & C2FrameData::FLAG_CODEC_CONFIG) {
hasPicture = false;
@@ -903,9 +882,50 @@
removePts(mPts);
}
+ bool whChanged = false;
+ if (GoldfishHevcHelper::isVpsFrame(mInPBuffer, mInPBufferSize)) {
+ mHevcHelper.reset(new GoldfishHevcHelper(mWidth, mHeight));
+ whChanged = mHevcHelper->decodeHeader(mInPBuffer, mInPBufferSize);
+ if (whChanged) {
+ DDD("w changed from old %d to new %d\n", mWidth, mHevcHelper->getWidth());
+ DDD("h changed from old %d to new %d\n", mHeight, mHevcHelper->getHeight());
+ if (1) {
+ drainInternal(DRAIN_COMPONENT_NO_EOS, pool, work);
+ resetDecoder();
+ resetPlugin();
+ work->workletsProcessed = 0u;
+ }
+ {
+ mWidth = mHevcHelper->getWidth();
+ mHeight = mHevcHelper->getHeight();
+ C2StreamPictureSizeInfo::output size(0u, mWidth, mHeight);
+ std::vector<std::unique_ptr<C2SettingResult>> failures;
+ c2_status_t err = mIntf->config({&size}, C2_MAY_BLOCK, &failures);
+ if (err == OK) {
+ work->worklets.front()->output.configUpdate.push_back(
+ C2Param::Copy(size));
+ ensureDecoderState(pool);
+ } else {
+ ALOGE("Cannot set width and height");
+ mSignalledError = true;
+ work->workletsProcessed = 1u;
+ work->result = C2_CORRUPTED;
+ return;
+ }
+ }
+ if (!mContext) {
+ DDD("creating decoder context to host in process work");
+ checkMode(pool);
+ createDecoder();
+ }
+ continue;//return;
+ } // end of whChanged
+ } // end of isVpsFrame
+
uint32_t delay;
GETTIME(&mTimeStart, nullptr);
TIME_DIFF(mTimeEnd, mTimeStart, delay);
+ (void)delay;
//(void) ivdec_api_function(mDecHandle, &s_decode_ip, &s_decode_op);
DDD("decoding");
hevc_result_t hevcRes =
@@ -922,44 +942,9 @@
uint32_t decodeTime;
GETTIME(&mTimeEnd, nullptr);
TIME_DIFF(mTimeStart, mTimeEnd, decodeTime);
- }
- // TODO: handle res change
- if (0) {
- DDD("resolution changed");
- drainInternal(DRAIN_COMPONENT_NO_EOS, pool, work);
- resetDecoder();
- resetPlugin();
- work->workletsProcessed = 0u;
-
- /* Decode header and get new dimensions */
- setParams(mStride);
- // (void) ivdec_api_function(mDecHandle, &s_decode_ip,
- // &s_decode_op);
+ (void)decodeTime;
}
if (mImg.data != nullptr) {
- // check for new width and height
- auto decodedW = mImg.width;
- auto decodedH = mImg.height;
- if (decodedW != mWidth || decodedH != mHeight) {
- mWidth = decodedW;
- mHeight = decodedH;
-
- C2StreamPictureSizeInfo::output size(0u, mWidth, mHeight);
- std::vector<std::unique_ptr<C2SettingResult>> failures;
- c2_status_t err = mIntf->config({&size}, C2_MAY_BLOCK, &failures);
- if (err == OK) {
- work->worklets.front()->output.configUpdate.push_back(
- C2Param::Copy(size));
- ensureDecoderState(pool);
- } else {
- ALOGE("Cannot set width and height");
- mSignalledError = true;
- work->workletsProcessed = 1u;
- work->result = C2_CORRUPTED;
- return;
- }
- }
-
DDD("got data %" PRIu64 " with pts %" PRIu64, getWorkIndex(mImg.pts), mImg.pts);
mHeaderDecoded = true;
copyImageData(mImg);
diff --git a/system/codecs/c2/decoders/hevcdec/C2GoldfishHevcDec.h b/system/codecs/c2/decoders/hevcdec/C2GoldfishHevcDec.h
index 575689a..fe080cf 100644
--- a/system/codecs/c2/decoders/hevcdec/C2GoldfishHevcDec.h
+++ b/system/codecs/c2/decoders/hevcdec/C2GoldfishHevcDec.h
@@ -22,6 +22,7 @@
#include <media/stagefright/foundation/ColorUtils.h>
#include "MediaHevcDecoder.h"
+#include "GoldfishHevcHelper.h"
#include <SimpleC2Component.h>
#include <atomic>
#include <map>
@@ -152,6 +153,8 @@
std::vector<uint8_t> mCsd1;
void decodeHeaderAfterFlush();
+ std::unique_ptr<GoldfishHevcHelper> mHevcHelper;
+
C2_DO_NOT_COPY(C2GoldfishHevcDec);
};
diff --git a/system/codecs/c2/decoders/hevcdec/GoldfishHevcHelper.cpp b/system/codecs/c2/decoders/hevcdec/GoldfishHevcHelper.cpp
new file mode 100644
index 0000000..1b93a0d
--- /dev/null
+++ b/system/codecs/c2/decoders/hevcdec/GoldfishHevcHelper.cpp
@@ -0,0 +1,315 @@
+/*
+ * Copyright 2022 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.
+ */
+
+#include "GoldfishHevcHelper.h"
+
+#define LOG_TAG "GoldfishHevcHelper"
+#include <log/log.h>
+
+#include "ihevc_typedefs.h"
+#include "ihevcd_cxa.h"
+
+#define DEBUG 0
+#if DEBUG
+#define DDD(...) ALOGD(__VA_ARGS__)
+#else
+#define DDD(...) ((void)0)
+#endif
+
+
+#include <Codec2Mapper.h>
+
+#define ivdec_api_function ihevcd_cxa_api_function
+#define ivdext_create_ip_t ihevcd_cxa_create_ip_t
+#define ivdext_create_op_t ihevcd_cxa_create_op_t
+#define ivdext_delete_ip_t ihevcd_cxa_delete_ip_t
+#define ivdext_delete_op_t ihevcd_cxa_delete_op_t
+#define ivdext_ctl_set_num_cores_ip_t ihevcd_cxa_ctl_set_num_cores_ip_t
+#define ivdext_ctl_set_num_cores_op_t ihevcd_cxa_ctl_set_num_cores_op_t
+#define ivdext_ctl_get_vui_params_ip_t ihevcd_cxa_ctl_get_vui_params_ip_t
+#define ivdext_ctl_get_vui_params_op_t ihevcd_cxa_ctl_get_vui_params_op_t
+#define ALIGN128(x) ((((x) + 127) >> 7) << 7)
+#define MAX_NUM_CORES 4
+#define IVDEXT_CMD_CTL_SET_NUM_CORES \
+ (IVD_CONTROL_API_COMMAND_TYPE_T) IHEVCD_CXA_CMD_CTL_SET_NUM_CORES
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+
+namespace android {
+
+static void *ivd_aligned_malloc(void *ctxt, WORD32 alignment, WORD32 size) {
+ (void) ctxt;
+ return memalign(alignment, size);
+}
+
+static void ivd_aligned_free(void *ctxt, void *mem) {
+ (void) ctxt;
+ free(mem);
+}
+
+
+GoldfishHevcHelper::GoldfishHevcHelper(int w, int h):mWidth(w),mHeight(h) { createDecoder(); }
+
+GoldfishHevcHelper::~GoldfishHevcHelper() {
+ destroyDecoder();
+}
+
+void GoldfishHevcHelper::createDecoder() {
+ ivdext_create_ip_t s_create_ip = {};
+ ivdext_create_op_t s_create_op = {};
+
+ s_create_ip.s_ivd_create_ip_t.u4_size = sizeof(ivdext_create_ip_t);
+ s_create_ip.s_ivd_create_ip_t.e_cmd = IVD_CMD_CREATE;
+ s_create_ip.s_ivd_create_ip_t.u4_share_disp_buf = 0;
+ s_create_ip.s_ivd_create_ip_t.e_output_format = mIvColorformat;
+ s_create_ip.s_ivd_create_ip_t.pf_aligned_alloc = ivd_aligned_malloc;
+ s_create_ip.s_ivd_create_ip_t.pf_aligned_free = ivd_aligned_free;
+ s_create_ip.s_ivd_create_ip_t.pv_mem_ctxt = nullptr;
+ s_create_op.s_ivd_create_op_t.u4_size = sizeof(ivdext_create_op_t);
+ IV_API_CALL_STATUS_T status =
+ ivdec_api_function(mDecHandle, &s_create_ip, &s_create_op);
+ if (status != IV_SUCCESS) {
+ ALOGE("error in %s: 0x%x", __func__,
+ s_create_op.s_ivd_create_op_t.u4_error_code);
+ return;
+ }
+ mDecHandle = (iv_obj_t *)s_create_op.s_ivd_create_op_t.pv_handle;
+ mDecHandle->pv_fxns = (void *)ivdec_api_function;
+ mDecHandle->u4_size = sizeof(iv_obj_t);
+
+ mStride = ALIGN128(mWidth);
+
+ setNumCores();
+}
+
+void GoldfishHevcHelper::destroyDecoder() {
+ if (mDecHandle) {
+ ivdext_delete_ip_t s_delete_ip = {};
+ ivdext_delete_op_t s_delete_op = {};
+
+ s_delete_ip.s_ivd_delete_ip_t.u4_size = sizeof(ivdext_delete_ip_t);
+ s_delete_ip.s_ivd_delete_ip_t.e_cmd = IVD_CMD_DELETE;
+ s_delete_op.s_ivd_delete_op_t.u4_size = sizeof(ivdext_delete_op_t);
+ IV_API_CALL_STATUS_T status =
+ ivdec_api_function(mDecHandle, &s_delete_ip, &s_delete_op);
+ if (status != IV_SUCCESS) {
+ ALOGE("error in %s: 0x%x", __func__,
+ s_delete_op.s_ivd_delete_op_t.u4_error_code);
+ }
+ mDecHandle = nullptr;
+ }
+}
+
+void GoldfishHevcHelper::setNumCores() {
+ ivdext_ctl_set_num_cores_ip_t s_set_num_cores_ip = {};
+ ivdext_ctl_set_num_cores_op_t s_set_num_cores_op = {};
+
+ s_set_num_cores_ip.u4_size = sizeof(ivdext_ctl_set_num_cores_ip_t);
+ s_set_num_cores_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_set_num_cores_ip.e_sub_cmd = IVDEXT_CMD_CTL_SET_NUM_CORES;
+ s_set_num_cores_ip.u4_num_cores = mNumCores;
+ s_set_num_cores_op.u4_size = sizeof(ivdext_ctl_set_num_cores_op_t);
+ IV_API_CALL_STATUS_T status = ivdec_api_function(
+ mDecHandle, &s_set_num_cores_ip, &s_set_num_cores_op);
+ if (IV_SUCCESS != status) {
+ DDD("error in %s: 0x%x", __func__, s_set_num_cores_op.u4_error_code);
+ }
+}
+
+void GoldfishHevcHelper::resetDecoder() {
+ ivd_ctl_reset_ip_t s_reset_ip = {};
+ ivd_ctl_reset_op_t s_reset_op = {};
+
+ s_reset_ip.u4_size = sizeof(ivd_ctl_reset_ip_t);
+ s_reset_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_reset_ip.e_sub_cmd = IVD_CMD_CTL_RESET;
+ s_reset_op.u4_size = sizeof(ivd_ctl_reset_op_t);
+ IV_API_CALL_STATUS_T status =
+ ivdec_api_function(mDecHandle, &s_reset_ip, &s_reset_op);
+ if (IV_SUCCESS != status) {
+ ALOGE("error in %s: 0x%x", __func__, s_reset_op.u4_error_code);
+ }
+ setNumCores();
+}
+
+void GoldfishHevcHelper::setParams(size_t stride,
+ IVD_VIDEO_DECODE_MODE_T dec_mode) {
+ ihevcd_cxa_ctl_set_config_ip_t s_hevcd_set_dyn_params_ip = {};
+ ihevcd_cxa_ctl_set_config_op_t s_hevcd_set_dyn_params_op = {};
+ ivd_ctl_set_config_ip_t *ps_set_dyn_params_ip =
+ &s_hevcd_set_dyn_params_ip.s_ivd_ctl_set_config_ip_t;
+ ivd_ctl_set_config_op_t *ps_set_dyn_params_op =
+ &s_hevcd_set_dyn_params_op.s_ivd_ctl_set_config_op_t;
+
+ ps_set_dyn_params_ip->u4_size = sizeof(ihevcd_cxa_ctl_set_config_ip_t);
+ ps_set_dyn_params_ip->e_cmd = IVD_CMD_VIDEO_CTL;
+ ps_set_dyn_params_ip->e_sub_cmd = IVD_CMD_CTL_SETPARAMS;
+ ps_set_dyn_params_ip->u4_disp_wd = (UWORD32)stride;
+ ps_set_dyn_params_ip->e_frm_skip_mode = IVD_SKIP_NONE;
+ ps_set_dyn_params_ip->e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
+ ps_set_dyn_params_ip->e_vid_dec_mode = dec_mode;
+ ps_set_dyn_params_op->u4_size = sizeof(ihevcd_cxa_ctl_set_config_op_t);
+ IV_API_CALL_STATUS_T status = ivdec_api_function(
+ mDecHandle, ps_set_dyn_params_ip, ps_set_dyn_params_op);
+ if (status != IV_SUCCESS) {
+ ALOGE("error in %s: 0x%x", __func__,
+ ps_set_dyn_params_op->u4_error_code);
+ }
+}
+
+bool GoldfishHevcHelper::isVpsFrame(const uint8_t* frame, int inSize) {
+ if (inSize < 5) return false;
+ if (frame[0] == 0 && frame[1] == 0 && frame[2] == 0 && frame[3] == 1) {
+ const bool forbiddenBitIsInvalid = 0x80 & frame[4];
+ if (forbiddenBitIsInvalid) {
+ return false;
+ }
+ // nalu type is the lower 6 bits after shiftting to right 1 bit
+ uint8_t naluType = 0x3f & (frame[4] >> 1);
+ if (naluType == 32
+ || naluType == 33
+ || naluType == 34
+ ) return true;
+ else return false;
+ } else {
+ return false;
+ }
+}
+
+bool GoldfishHevcHelper::decodeHeader(const uint8_t *frame, int inSize) {
+ // should we check the header for vps/sps/pps frame ? otherwise
+ // there is no point calling decoder
+ if (!isVpsFrame(frame, inSize)) {
+ DDD("could not find valid vps frame");
+ return false;
+ } else {
+ DDD("found valid vps frame");
+ }
+
+ ihevcd_cxa_video_decode_ip_t s_hevcd_decode_ip = {};
+ ihevcd_cxa_video_decode_op_t s_hevcd_decode_op = {};
+ ivd_video_decode_ip_t *ps_decode_ip =
+ &s_hevcd_decode_ip.s_ivd_video_decode_ip_t;
+ ivd_video_decode_op_t *ps_decode_op =
+ &s_hevcd_decode_op.s_ivd_video_decode_op_t;
+
+ // setup input/output arguments to decoder
+ setDecodeArgs(ps_decode_ip, ps_decode_op, frame, mStride,
+ 0, // offset
+ inSize, // size
+ 0 // time-stamp, does not matter
+ );
+
+ setParams(mStride, IVD_DECODE_HEADER);
+
+ // now kick off the decoding
+ IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle, ps_decode_ip, ps_decode_op);
+ if (status != IV_SUCCESS) {
+ ALOGE("failed to call decoder function for header\n");
+ ALOGE("error in %s: 0x%x", __func__,
+ ps_decode_op->u4_error_code);
+ }
+
+ if (IVD_RES_CHANGED == (ps_decode_op->u4_error_code & IVD_ERROR_MASK)) {
+ DDD("resolution changed, reset decoder");
+ resetDecoder();
+ setParams(mStride, IVD_DECODE_HEADER);
+ ivdec_api_function(mDecHandle, ps_decode_ip, ps_decode_op);
+ }
+
+ // get the w/h and update
+ if (0 < ps_decode_op->u4_pic_wd && 0 < ps_decode_op->u4_pic_ht) {
+ DDD("success decode w/h %d %d", ps_decode_op->u4_pic_wd , ps_decode_op->u4_pic_ht);
+ DDD("existing w/h %d %d", mWidth, mHeight);
+ if (ps_decode_op->u4_pic_wd != mWidth || ps_decode_op->u4_pic_ht != mHeight) {
+ mWidth = ps_decode_op->u4_pic_wd;
+ mHeight = ps_decode_op->u4_pic_ht;
+ return true;
+ } else {
+ DDD("success decode w/h, but they are the same %d %d", ps_decode_op->u4_pic_wd , ps_decode_op->u4_pic_ht);
+ }
+ } else {
+ ALOGE("could not decode w/h");
+ }
+
+ // get output delay
+ if (ps_decode_op->i4_reorder_depth >= 0) {
+ if (mOutputDelay != ps_decode_op->i4_reorder_depth) {
+ mOutputDelay = ps_decode_op->i4_reorder_depth;
+ DDD("New Output delay %d ", mOutputDelay);
+ } else {
+ DDD("same Output delay %d ", mOutputDelay);
+ }
+ }
+
+ return false;
+}
+
+bool GoldfishHevcHelper::setDecodeArgs(ivd_video_decode_ip_t *ps_decode_ip,
+ ivd_video_decode_op_t *ps_decode_op,
+ const uint8_t *inBuffer,
+ uint32_t displayStride, size_t inOffset,
+ size_t inSize, uint32_t tsMarker) {
+ uint32_t displayHeight = mHeight;
+ size_t lumaSize = displayStride * displayHeight;
+ size_t chromaSize = lumaSize >> 2;
+
+ if (mStride != displayStride) {
+ mStride = displayStride;
+ }
+
+ // force decoder to always decode header and get dimensions,
+ // hope this will be quick and cheap
+ setParams(mStride, IVD_DECODE_HEADER);
+
+ ps_decode_ip->u4_size = sizeof(ihevcd_cxa_video_decode_ip_t);
+ ps_decode_ip->e_cmd = IVD_CMD_VIDEO_DECODE;
+ if (inBuffer) {
+ ps_decode_ip->u4_ts = tsMarker;
+ ps_decode_ip->pv_stream_buffer = const_cast<uint8_t *>(inBuffer) + inOffset;
+ ps_decode_ip->u4_num_Bytes = inSize;
+ } else {
+ ps_decode_ip->u4_ts = 0;
+ ps_decode_ip->pv_stream_buffer = nullptr;
+ ps_decode_ip->u4_num_Bytes = 0;
+ }
+ DDD("setting pv_stream_buffer 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
+ ((uint8_t*)(ps_decode_ip->pv_stream_buffer))[0],
+ ((uint8_t*)(ps_decode_ip->pv_stream_buffer))[1],
+ ((uint8_t*)(ps_decode_ip->pv_stream_buffer))[2],
+ ((uint8_t*)(ps_decode_ip->pv_stream_buffer))[3],
+ ((uint8_t*)(ps_decode_ip->pv_stream_buffer))[4],
+ ((uint8_t*)(ps_decode_ip->pv_stream_buffer))[5],
+ ((uint8_t*)(ps_decode_ip->pv_stream_buffer))[6],
+ ((uint8_t*)(ps_decode_ip->pv_stream_buffer))[7]
+ );
+ DDD("input bytes %d", ps_decode_ip->u4_num_Bytes);
+
+ ps_decode_ip->s_out_buffer.u4_min_out_buf_size[0] = lumaSize;
+ ps_decode_ip->s_out_buffer.u4_min_out_buf_size[1] = chromaSize;
+ ps_decode_ip->s_out_buffer.u4_min_out_buf_size[2] = chromaSize;
+ {
+ ps_decode_ip->s_out_buffer.pu1_bufs[0] = nullptr;
+ ps_decode_ip->s_out_buffer.pu1_bufs[1] = nullptr;
+ ps_decode_ip->s_out_buffer.pu1_bufs[2] = nullptr;
+ }
+ ps_decode_ip->s_out_buffer.u4_num_bufs = 3;
+ ps_decode_op->u4_size = sizeof(ihevcd_cxa_video_decode_op_t);
+ ps_decode_op->u4_output_present = 0;
+
+ return true;
+}
+
+} // namespace android
diff --git a/system/codecs/c2/decoders/hevcdec/GoldfishHevcHelper.h b/system/codecs/c2/decoders/hevcdec/GoldfishHevcHelper.h
new file mode 100644
index 0000000..09de830
--- /dev/null
+++ b/system/codecs/c2/decoders/hevcdec/GoldfishHevcHelper.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2022 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 GOLDFISH_HEVC_HELPER_H_
+#define GOLDFISH_HEVC_HELPER_H_
+
+#include <inttypes.h>
+#include "ihevc_typedefs.h"
+#include "ihevcd_cxa.h"
+
+
+namespace android {
+
+// this class is just to provide some functions to decode header
+// so that we know w/h of each sps
+class GoldfishHevcHelper {
+ public:
+ GoldfishHevcHelper(int w, int h);
+ ~GoldfishHevcHelper();
+
+ // check whether the frame is vps; typical hevc will have
+ // a frame that is vps/sps/pps together
+ static bool isVpsFrame(const uint8_t* frame, int inSize);
+ public:
+ // return true if decoding finds out w/h changed;
+ // otherwise false
+ bool decodeHeader(const uint8_t *frame, int inSize);
+ int getWidth() const { return mWidth; }
+ int getHeight() const { return mHeight; }
+
+ private:
+ void createDecoder();
+ void destroyDecoder();
+ void resetDecoder();
+ void setNumCores();
+ void setParams(size_t stride, IVD_VIDEO_DECODE_MODE_T dec_mode);
+ bool setDecodeArgs(ivd_video_decode_ip_t *ps_decode_ip,
+ ivd_video_decode_op_t *ps_decode_op,
+ const uint8_t *inBuffer, uint32_t displayStride,
+ size_t inOffset, size_t inSize, uint32_t tsMarker);
+
+ private:
+ iv_obj_t *mDecHandle = nullptr;
+ int mWidth = 320;
+ int mHeight = 240;
+ int mNumCores = 1;
+ int mStride = 16;
+ int mOutputDelay = 8; // default
+ IV_COLOR_FORMAT_T mIvColorformat = IV_YUV_420P;
+};
+
+} // namespace android
+#endif
diff --git a/system/codecs/c2/decoders/vpxdec/C2GoldfishVpxDec.cpp b/system/codecs/c2/decoders/vpxdec/C2GoldfishVpxDec.cpp
index 99ddcfd..99f0469 100644
--- a/system/codecs/c2/decoders/vpxdec/C2GoldfishVpxDec.cpp
+++ b/system/codecs/c2/decoders/vpxdec/C2GoldfishVpxDec.cpp
@@ -465,32 +465,14 @@
mCtx = new vpx_codec_ctx_t;
mCtx->vpversion = mMode == MODE_VP8 ? 8 : 9;
- // check for decoding mode:
- {
- // now get the block
- constexpr uint32_t format = HAL_PIXEL_FORMAT_YCBCR_420_888;
- std::shared_ptr<C2GraphicBlock> block;
- C2MemoryUsage usage = {C2MemoryUsage::CPU_READ,
- C2MemoryUsage::CPU_WRITE};
- usage.expected = (uint64_t)(BufferUsage::VIDEO_DECODER);
-
- c2_status_t err = pool->fetchGraphicBlock(align(mWidth, 2), mHeight,
- format, usage, &block);
- if (err != C2_OK) {
- ALOGE("fetchGraphicBlock for Output failed with status %d", err);
- return;
- }
- auto c2Handle = block->handle();
- native_handle_t *grallocHandle =
- UnwrapNativeCodec2GrallocHandle(c2Handle);
- int hostColorBufferId = getColorBufferHandle(grallocHandle);
- if (hostColorBufferId > 0) {
- DDD("decoding to host color buffer");
- mEnableAndroidNativeBuffers = true;
- } else {
- DDD("decoding to guest byte buffer");
- mEnableAndroidNativeBuffers = false;
- }
+ const bool isGraphic = (pool->getAllocatorId() & C2Allocator::GRAPHIC);
+ DDD("buffer id %d", (int)(pool->getAllocatorId()));
+ if (isGraphic) {
+ DDD("decoding to host color buffer");
+ mEnableAndroidNativeBuffers = true;
+ } else {
+ DDD("decoding to guest byte buffer");
+ mEnableAndroidNativeBuffers = false;
}
mCtx->version = mEnableAndroidNativeBuffers ? 200 : 100;
@@ -721,24 +703,24 @@
return UNKNOWN_ERROR;
}
- bool decodingToByteBuffer = false;
- {
+ int hostColorBufferId = -1;
+ const bool decodingToHostColorBuffer = mEnableAndroidNativeBuffers;
+ if(decodingToHostColorBuffer){
auto c2Handle = block->handle();
native_handle_t *grallocHandle =
UnwrapNativeCodec2GrallocHandle(c2Handle);
- int hostColorBufferId = getColorBufferHandle(grallocHandle);
+ hostColorBufferId = getColorBufferHandle(grallocHandle);
if (hostColorBufferId > 0) {
DDD("found handle %d", hostColorBufferId);
} else {
- decodingToByteBuffer = true;
DDD("decode to buffer, because handle %d is invalid",
hostColorBufferId);
// change to -1 so host knows it is definitely invalid
// 0 is a bit confusing
hostColorBufferId = -1;
}
- setup_ctx_parameters(mCtx, hostColorBufferId);
}
+ setup_ctx_parameters(mCtx, hostColorBufferId);
vpx_image_t *img = vpx_codec_get_frame(mCtx);
@@ -798,7 +780,7 @@
}
}
- if (decodingToByteBuffer) {
+ if (!decodingToHostColorBuffer) {
C2GraphicView wView = block->map().get();
if (wView.error()) {