Commit f668a4b5 by Jamie Madill Committed by Commit Bot

Skip Texture::syncState when no dirty bits.

We sometimes generate local dirty bits in TextureGL. To make sure the local dirty bits don't get skipped we use a Subject/Observer pattern between the TextureGL and gl::Texture. This allows us to skip syncState in the hot path. Also inlines a couple of other texture functions. And fixes a stray header in EGLBlobCacheTest. Bug: angleproject:2763 Change-Id: Ie1d8a5865deaf2a563a358c31ae28bef6b2458b1 Reviewed-on: https://chromium-review.googlesource.com/1228374 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarYuly Novikov <ynovikov@chromium.org>
parent 77db6f4a
......@@ -1828,7 +1828,12 @@ void Framebuffer::onSubjectStateChange(const Context *context,
angle::SubjectIndex index,
angle::SubjectMessage message)
{
ASSERT(message == angle::SubjectMessage::STORAGE_CHANGED);
if (message != angle::SubjectMessage::STORAGE_CHANGED)
{
// This can be triggered by the GL back-end TextureGL class.
ASSERT(message == angle::SubjectMessage::DEPENDENT_DIRTY_BITS);
return;
}
ASSERT(!mDirtyBitsGuard.valid() || mDirtyBitsGuard.value().test(index));
mDirtyBits.set(index);
......
......@@ -361,11 +361,6 @@ void FramebufferAttachmentObject::onStorageChange(const gl::Context *context) co
return getAttachmentImpl()->onStateChange(context, angle::SubjectMessage::STORAGE_CHANGED);
}
angle::Subject *FramebufferAttachmentObject::getSubject() const
{
return getAttachmentImpl();
}
Error FramebufferAttachmentObject::initializeContents(const Context *context,
const ImageIndex &imageIndex)
{
......
......@@ -15,6 +15,7 @@
#include "libANGLE/Error.h"
#include "libANGLE/ImageIndex.h"
#include "libANGLE/formatutils.h"
#include "libANGLE/renderer/FramebufferAttachmentObjectImpl.h"
namespace egl
{
......@@ -220,7 +221,7 @@ class FramebufferAttachmentObject
Error initializeContents(const Context *context, const ImageIndex &imageIndex);
void onStorageChange(const gl::Context *context) const;
angle::Subject *getSubject() const;
angle::Subject *getSubject() const { return getAttachmentImpl(); }
protected:
virtual rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const = 0;
......
......@@ -25,6 +25,7 @@
#include "libANGLE/queryconversions.h"
#include "libANGLE/queryutils.h"
#include "libANGLE/renderer/ContextImpl.h"
#include "libANGLE/renderer/TextureImpl.h"
namespace gl
{
......@@ -2756,7 +2757,10 @@ Error State::syncProgramTextures(const Context *context)
// TODO(jmadill): Use specific dirty bit for completeness change.
if (texture->isSamplerComplete(context, sampler))
{
ANGLE_TRY(texture->syncState(context));
if (texture->hasAnyDirtyBit())
{
ANGLE_TRY(texture->syncState(context));
}
mActiveTexturesCache[textureUnitIndex] = texture;
}
else
......@@ -2765,7 +2769,7 @@ Error State::syncProgramTextures(const Context *context)
}
// Bind the texture unconditionally, to recieve completeness change notifications.
mCompleteTextureBindings[textureUnitIndex].bind(texture->getSubject());
mCompleteTextureBindings[textureUnitIndex].bind(texture->getImplementation());
newActiveTextures.set(textureUnitIndex);
if (texture->initState() == InitState::MayNeedInit)
......@@ -2792,7 +2796,10 @@ Error State::syncProgramTextures(const Context *context)
{
continue;
}
ANGLE_TRY(texture->syncState(context));
if (texture->hasAnyDirtyBit())
{
ANGLE_TRY(texture->syncState(context));
}
if (texture->initState() == InitState::MayNeedInit)
{
mCachedImageTexturesInitState = InitState::MayNeedInit;
......
......@@ -584,10 +584,15 @@ Texture::Texture(rx::GLImplFactory *factory, GLuint id, TextureType type)
: RefCountObject(id),
mState(type),
mTexture(factory->createTexture(mState)),
mImplObserver(this, 0),
mLabel(),
mBoundSurface(nullptr),
mBoundStream(nullptr)
{
mImplObserver.bind(mTexture);
// Initially assume the implementation is dirty.
mDirtyBits.set(DIRTY_BIT_IMPLEMENTATION);
}
Error Texture::onDestroy(const Context *context)
......@@ -1255,7 +1260,11 @@ Error Texture::generateMipmap(const Context *context)
{
return NoError();
}
ANGLE_TRY(syncState(context));
if (hasAnyDirtyBit())
{
ANGLE_TRY(syncState(context));
}
// Clear the base image(s) immediately if needed
if (context->isRobustResourceInitEnabled())
......@@ -1515,6 +1524,7 @@ GLuint Texture::getId() const
Error Texture::syncState(const Context *context)
{
ASSERT(hasAnyDirtyBit());
ANGLE_TRY(mTexture->syncState(context, mDirtyBits));
mDirtyBits.reset();
return NoError();
......@@ -1607,11 +1617,6 @@ InitState Texture::initState(const ImageIndex &imageIndex) const
return mState.getImageDesc(imageIndex).initState;
}
InitState Texture::initState() const
{
return mState.mInitState;
}
void Texture::setInitState(const ImageIndex &imageIndex, InitState initState)
{
// As an ImageIndex that represents an entire level of a cube map corresponds to 6 ImageDescs,
......@@ -1673,4 +1678,13 @@ Error Texture::handleMipmapGenerationHint(const Context *context, int level)
return NoError();
}
void Texture::onSubjectStateChange(const gl::Context *context,
angle::SubjectIndex index,
angle::SubjectMessage message)
{
if (message == angle::SubjectMessage::DEPENDENT_DIRTY_BITS)
{
mDirtyBits.set(DIRTY_BIT_IMPLEMENTATION);
}
}
} // namespace gl
......@@ -21,6 +21,7 @@
#include "libANGLE/Error.h"
#include "libANGLE/FramebufferAttachment.h"
#include "libANGLE/Image.h"
#include "libANGLE/Observer.h"
#include "libANGLE/Stream.h"
#include "libANGLE/angletypes.h"
#include "libANGLE/formatutils.h"
......@@ -187,7 +188,10 @@ struct TextureState final : private angle::NonCopyable
bool operator==(const TextureState &a, const TextureState &b);
bool operator!=(const TextureState &a, const TextureState &b);
class Texture final : public RefCountObject, public egl::ImageSibling, public LabeledObject
class Texture final : public RefCountObject,
public egl::ImageSibling,
public LabeledObject,
public angle::ObserverInterface
{
public:
Texture(rx::GLImplFactory *factory, GLuint id, TextureType type);
......@@ -397,7 +401,7 @@ class Texture final : public RefCountObject, public egl::ImageSibling, public La
// Needed for robust resource init.
Error ensureInitialized(const Context *context);
InitState initState(const ImageIndex &imageIndex) const override;
InitState initState() const;
InitState initState() const { return mState.mInitState; }
void setInitState(const ImageIndex &imageIndex, InitState initState) override;
enum DirtyBitType
......@@ -427,6 +431,7 @@ class Texture final : public RefCountObject, public egl::ImageSibling, public La
// Misc
DIRTY_BIT_LABEL,
DIRTY_BIT_USAGE,
DIRTY_BIT_IMPLEMENTATION,
DIRTY_BIT_COUNT,
};
......@@ -435,6 +440,11 @@ class Texture final : public RefCountObject, public egl::ImageSibling, public La
Error syncState(const Context *context);
bool hasAnyDirtyBit() const { return mDirtyBits.any(); }
// ObserverInterface implementation.
void onSubjectStateChange(const gl::Context *context,
angle::SubjectIndex index,
angle::SubjectMessage message) override;
private:
rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const override;
......@@ -464,6 +474,7 @@ class Texture final : public RefCountObject, public egl::ImageSibling, public La
TextureState mState;
DirtyBits mDirtyBits;
rx::TextureImpl *mTexture;
angle::ObserverBinding mImplObserver;
std::string mLabel;
......
......@@ -11,11 +11,12 @@
#ifndef LIBANGLE_RENDERER_FRAMEBUFFER_ATTACHMENT_OBJECT_IMPL_H_
#define LIBANGLE_RENDERER_FRAMEBUFFER_ATTACHMENT_OBJECT_IMPL_H_
#include "libANGLE/FramebufferAttachment.h"
#include "libANGLE/ImageIndex.h"
#include "libANGLE/Observer.h"
namespace rx
{
class FramebufferAttachmentRenderTarget;
class FramebufferAttachmentObjectImpl : public angle::Subject
{
......
......@@ -235,7 +235,8 @@ void TextureGL::setImageHelper(const gl::Context *context,
UNREACHABLE();
}
setLevelInfo(target, level, 1, GetLevelInfo(internalFormat, texImageFormat.internalFormat));
setLevelInfo(context, target, level, 1,
GetLevelInfo(internalFormat, texImageFormat.internalFormat));
}
void TextureGL::reserveTexImageToBeFilled(const gl::Context *context,
......@@ -508,7 +509,7 @@ gl::Error TextureGL::setCompressedImage(const gl::Context *context,
LevelInfoGL levelInfo = GetLevelInfo(internalFormat, compressedTexImageFormat.internalFormat);
ASSERT(!levelInfo.lumaWorkaround.enabled);
setLevelInfo(target, level, 1, levelInfo);
setLevelInfo(context, target, level, 1, levelInfo);
return gl::NoError();
}
......@@ -660,7 +661,7 @@ gl::Error TextureGL::copyImage(const gl::Context *context,
UNREACHABLE();
}
setLevelInfo(target, level, 1, levelInfo);
setLevelInfo(context, target, level, 1, levelInfo);
}
return gl::NoError();
......@@ -1007,7 +1008,8 @@ gl::Error TextureGL::setStorage(const gl::Context *context,
UNREACHABLE();
}
setLevelInfo(type, 0, levels, GetLevelInfo(internalFormat, texStorageFormat.internalFormat));
setLevelInfo(context, type, 0, levels,
GetLevelInfo(internalFormat, texStorageFormat.internalFormat));
return gl::NoError();
}
......@@ -1046,7 +1048,8 @@ gl::Error TextureGL::setStorageMultisample(const gl::Context *context,
UNREACHABLE();
}
setLevelInfo(type, 0, 1, GetLevelInfo(internalFormat, texStorageFormat.internalFormat));
setLevelInfo(context, type, 0, 1,
GetLevelInfo(internalFormat, texStorageFormat.internalFormat));
return gl::NoError();
}
......@@ -1071,7 +1074,8 @@ gl::Error TextureGL::generateMipmap(const gl::Context *context)
const GLuint effectiveBaseLevel = mState.getEffectiveBaseLevel();
const GLuint maxLevel = mState.getMipmapMaxLevel();
setLevelInfo(getType(), effectiveBaseLevel, maxLevel - effectiveBaseLevel, getBaseLevelInfo());
setLevelInfo(context, getType(), effectiveBaseLevel, maxLevel - effectiveBaseLevel,
getBaseLevelInfo());
return gl::NoError();
}
......@@ -1085,7 +1089,7 @@ gl::Error TextureGL::bindTexImage(const gl::Context *context, egl::Surface *surf
// Make sure this texture is bound
stateManager->bindTexture(getType(), mTextureID);
setLevelInfo(getType(), 0, 1, LevelInfoGL());
setLevelInfo(context, getType(), 0, 1, LevelInfoGL());
return gl::NoError();
}
......@@ -1119,7 +1123,7 @@ gl::Error TextureGL::setEGLImageTarget(const gl::Context *context,
GLenum imageNativeInternalFormat = GL_NONE;
ANGLE_TRY(imageGL->setTexture2D(context, type, this, &imageNativeInternalFormat));
setLevelInfo(type, 0, 1,
setLevelInfo(context, type, 0, 1,
GetLevelInfo(image->getFormat().info->internalFormat, imageNativeInternalFormat));
return gl::NoError();
......@@ -1247,6 +1251,11 @@ gl::Error TextureGL::syncState(const gl::Context *context, const gl::Texture::Di
case gl::Texture::DIRTY_BIT_LABEL:
break;
case gl::Texture::DIRTY_BIT_IMPLEMENTATION:
// This special dirty bit is used to signal the front-end that the implementation
// has local dirty bits. The real dirty bits are in mLocalDirty bits.
break;
default:
UNREACHABLE();
}
......@@ -1271,6 +1280,9 @@ gl::Error TextureGL::setBaseLevel(const gl::Context *context, GLuint baseLevel)
mAppliedBaseLevel = baseLevel;
mLocalDirtyBits.set(gl::Texture::DIRTY_BIT_BASE_LEVEL);
// Signal to the GL layer that the Impl has dirty bits.
onStateChange(context, angle::SubjectMessage::DEPENDENT_DIRTY_BITS);
stateManager->bindTexture(getType(), mTextureID);
functions->texParameteri(ToGLenum(getType()), GL_TEXTURE_BASE_LEVEL, baseLevel);
}
......@@ -1287,6 +1299,9 @@ void TextureGL::setMinFilter(const gl::Context *context, GLenum filter)
mAppliedSampler.setMinFilter(filter);
mLocalDirtyBits.set(gl::Texture::DIRTY_BIT_MIN_FILTER);
// Signal to the GL layer that the Impl has dirty bits.
onStateChange(context, angle::SubjectMessage::DEPENDENT_DIRTY_BITS);
stateManager->bindTexture(getType(), mTextureID);
functions->texParameteri(ToGLenum(getType()), GL_TEXTURE_MIN_FILTER, filter);
}
......@@ -1301,6 +1316,9 @@ void TextureGL::setMagFilter(const gl::Context *context, GLenum filter)
mAppliedSampler.setMagFilter(filter);
mLocalDirtyBits.set(gl::Texture::DIRTY_BIT_MAG_FILTER);
// Signal to the GL layer that the Impl has dirty bits.
onStateChange(context, angle::SubjectMessage::DEPENDENT_DIRTY_BITS);
stateManager->bindTexture(getType(), mTextureID);
functions->texParameteri(ToGLenum(getType()), GL_TEXTURE_MAG_FILTER, filter);
}
......@@ -1322,6 +1340,9 @@ void TextureGL::setSwizzle(const gl::Context *context, GLint swizzle[4])
mLocalDirtyBits.set(gl::Texture::DIRTY_BIT_SWIZZLE_BLUE);
mLocalDirtyBits.set(gl::Texture::DIRTY_BIT_SWIZZLE_ALPHA);
// Signal to the GL layer that the Impl has dirty bits.
onStateChange(context, angle::SubjectMessage::DEPENDENT_DIRTY_BITS);
stateManager->bindTexture(getType(), mTextureID);
functions->texParameteriv(ToGLenum(getType()), GL_TEXTURE_SWIZZLE_RGBA, swizzle);
}
......@@ -1446,7 +1467,8 @@ void TextureGL::syncTextureStateSwizzle(const FunctionsGL *functions,
functions->texParameteri(ToGLenum(getType()), name, resultSwizzle);
}
void TextureGL::setLevelInfo(gl::TextureTarget target,
void TextureGL::setLevelInfo(const gl::Context *context,
gl::TextureTarget target,
size_t level,
size_t levelCount,
const LevelInfoGL &levelInfo)
......@@ -1470,10 +1492,12 @@ void TextureGL::setLevelInfo(gl::TextureTarget target,
if (updateWorkarounds)
{
mLocalDirtyBits |= GetLevelWorkaroundDirtyBits();
onStateChange(context, angle::SubjectMessage::DEPENDENT_DIRTY_BITS);
}
}
void TextureGL::setLevelInfo(gl::TextureType type,
void TextureGL::setLevelInfo(const gl::Context *context,
gl::TextureType type,
size_t level,
size_t levelCount,
const LevelInfoGL &levelInfo)
......@@ -1482,12 +1506,12 @@ void TextureGL::setLevelInfo(gl::TextureType type,
{
for (gl::TextureTarget target : gl::AllCubeFaceTextureTargets())
{
setLevelInfo(target, level, levelCount, levelInfo);
setLevelInfo(context, target, level, levelCount, levelInfo);
}
}
else
{
setLevelInfo(NonCubeTextureTypeToTarget(type), level, levelCount, levelInfo);
setLevelInfo(context, NonCubeTextureTypeToTarget(type), level, levelCount, levelInfo);
}
}
......
......@@ -223,11 +223,13 @@ class TextureGL : public TextureImpl
GLenum value,
GLenum *outValue);
void setLevelInfo(gl::TextureTarget target,
void setLevelInfo(const gl::Context *context,
gl::TextureTarget target,
size_t level,
size_t levelCount,
const LevelInfoGL &levelInfo);
void setLevelInfo(gl::TextureType type,
void setLevelInfo(const gl::Context *context,
gl::TextureType type,
size_t level,
size_t levelCount,
const LevelInfoGL &levelInfo);
......
......@@ -12,8 +12,6 @@
#include "test_utils/ANGLETest.h"
#include "test_utils/gl_raii.h"
#include "libANGLE/validationEGL.h"
using namespace angle;
constexpr char kEGLExtName[] = "EGL_ANDROID_blob_cache";
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment