Commit d0b270e6 by Jamie Madill Committed by Commit Bot

Feedback Loop Redesign 1/3: Framebuffer Serials.

Currently we track feedback loops by counting the times a Texture is bound as a sampler or image in a particular context. This is a bit tricky because Texture bindings change frequently. Relative to the number of times we need to check for a feedback loop this causes excess overhead. Usually Framebuffers have a low number of Textures bound (in many cases just 1). And Textures aren't usually bound to many different FBOs. So instead of counting the number of times a Texture is bound as a sampler or image we will track the Framebuffers that the Texture is bound to. Because FBOs are unique to a Context, a Texture could be bound to two different FBOs with the same ID. In this CL we introduce a new Serial for the FBO which is unique to an EGL Share Group. This way we can ensure we don't make the wrong call when a Texture is referenced by a Framebuffer. It also replaces the old FB serial which was again only unique to a particular Context. Bug: angleproject:4500 Bug: angleproject:4959 Change-Id: I0a9989d861a4132bd3b7ed85f699a4448ff37a4e Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2358849Reviewed-by: 's avatarJonah Ryan-Davis <jonahr@google.com> Reviewed-by: 's avatarTobin Ehlis <tobine@google.com> Reviewed-by: 's avatarCourtney Goeltzenleuchter <courtneygo@google.com> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 85919ef7
......@@ -1080,7 +1080,8 @@ void Context::bindTexture(TextureType target, TextureID handle)
void Context::bindReadFramebuffer(FramebufferID framebufferHandle)
{
Framebuffer *framebuffer = mState.mFramebufferManager->checkFramebufferAllocation(
mImplementation.get(), mState.mCaps, framebufferHandle, mState.getContextID());
mImplementation.get(), mState.mCaps, framebufferHandle, mState.getContextID(),
getShareGroup());
mState.setReadFramebufferBinding(framebuffer);
mReadFramebufferObserverBinding.bind(framebuffer);
}
......@@ -1088,7 +1089,8 @@ void Context::bindReadFramebuffer(FramebufferID framebufferHandle)
void Context::bindDrawFramebuffer(FramebufferID framebufferHandle)
{
Framebuffer *framebuffer = mState.mFramebufferManager->checkFramebufferAllocation(
mImplementation.get(), mState.mCaps, framebufferHandle, mState.getContextID());
mImplementation.get(), mState.mCaps, framebufferHandle, mState.getContextID(),
getShareGroup());
mState.setDrawFramebufferBinding(framebuffer);
mDrawFramebufferObserverBinding.bind(framebuffer);
mStateCache.onDrawFramebufferChange(this);
......
......@@ -632,6 +632,8 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl
void release() const { mRefCount--; }
size_t getRefCount() const { return mRefCount; }
egl::ShareGroup *getShareGroup() const { return mState.getShareGroup(); }
private:
void initialize();
......
......@@ -77,12 +77,15 @@ class ShareGroup final : angle::NonCopyable
rx::ShareGroupImpl *getImplementation() const { return mImplementation; }
rx::Serial generateFramebufferSerial() { return mFramebufferSerialFactory.generate(); }
protected:
~ShareGroup();
private:
size_t mRefCount;
rx::ShareGroupImpl *mImplementation;
rx::SerialFactory mFramebufferSerialFactory;
};
// Constant coded here as a sanity limit.
......
......@@ -265,8 +265,9 @@ angle::Result InitAttachment(const Context *context, FramebufferAttachment *atta
} // anonymous namespace
// This constructor is only used for default framebuffers.
FramebufferState::FramebufferState(ContextID owningContextID)
FramebufferState::FramebufferState(ContextID owningContextID, rx::Serial serial)
: mId(Framebuffer::kDefaultDrawFramebufferHandle),
mFramebufferSerial(serial),
mOwningContextID(owningContextID),
mLabel(),
mColorAttachments(1),
......@@ -288,8 +289,12 @@ FramebufferState::FramebufferState(ContextID owningContextID)
mEnabledDrawBuffers.set(0);
}
FramebufferState::FramebufferState(const Caps &caps, FramebufferID id, ContextID owningContextID)
FramebufferState::FramebufferState(const Caps &caps,
FramebufferID id,
ContextID owningContextID,
rx::Serial serial)
: mId(id),
mFramebufferSerial(serial),
mOwningContextID(owningContextID),
mLabel(),
mColorAttachments(caps.maxColorAttachments),
......@@ -708,9 +713,9 @@ const FramebufferID Framebuffer::kDefaultDrawFramebufferHandle = {0};
Framebuffer::Framebuffer(const Caps &caps,
rx::GLImplFactory *factory,
FramebufferID id,
ContextID owningContextID)
: mSerial(factory->generateSerial()),
mState(caps, id, owningContextID),
ContextID owningContextID,
egl::ShareGroup *shareGroup)
: mState(caps, id, owningContextID, shareGroup->generateFramebufferSerial()),
mImpl(factory->createFramebuffer(mState)),
mCachedStatus(),
mDirtyDepthAttachmentBinding(this, DIRTY_BIT_DEPTH_ATTACHMENT),
......@@ -728,8 +733,7 @@ Framebuffer::Framebuffer(const Caps &caps,
}
Framebuffer::Framebuffer(const Context *context, egl::Surface *surface, egl::Surface *readSurface)
: mSerial(context->getImplementation()->generateSerial()),
mState(context->id()),
: mState(context->id(), context->getShareGroup()->generateFramebufferSerial()),
mImpl(surface->getImplementation()->createDefaultFramebuffer(context, mState)),
mCachedStatus(GL_FRAMEBUFFER_COMPLETE),
mDirtyDepthAttachmentBinding(this, DIRTY_BIT_DEPTH_ATTACHMENT),
......@@ -771,7 +775,7 @@ Framebuffer::Framebuffer(const Context *context, egl::Surface *surface, egl::Sur
Framebuffer::Framebuffer(const Context *context,
rx::GLImplFactory *factory,
egl::Surface *readSurface)
: mState(context->id()),
: mState(context->id(), context->getShareGroup()->generateFramebufferSerial()),
mImpl(factory->createFramebuffer(mState)),
mCachedStatus(GL_FRAMEBUFFER_UNDEFINED_OES),
mDirtyDepthAttachmentBinding(this, DIRTY_BIT_DEPTH_ATTACHMENT),
......
......@@ -53,8 +53,11 @@ class TextureCapsMap;
class FramebufferState final : angle::NonCopyable
{
public:
explicit FramebufferState(ContextID owningContextID);
FramebufferState(const Caps &caps, FramebufferID id, ContextID owningContextID);
explicit FramebufferState(ContextID owningContextID, rx::Serial serial);
FramebufferState(const Caps &caps,
FramebufferID id,
ContextID owningContextID,
rx::Serial serial);
~FramebufferState();
const std::string &getLabel() const;
......@@ -123,6 +126,8 @@ class FramebufferState final : angle::NonCopyable
const gl::Offset &getSurfaceTextureOffset() const { return mSurfaceTextureOffset; }
rx::Serial getFramebufferSerial() const { return mFramebufferSerial; }
private:
const FramebufferAttachment *getWebGLDepthStencilAttachment() const;
const FramebufferAttachment *getWebGLDepthAttachment() const;
......@@ -134,7 +139,12 @@ class FramebufferState final : angle::NonCopyable
friend class Framebuffer;
// The Framebuffer ID is unique to a Context.
// The Framebuffer Serial is unique to a Share Group.
FramebufferID mId;
rx::Serial mFramebufferSerial;
// TODO(jmadill): Remove the owning context ID. http://anglebug.com/4500
ContextID mOwningContextID;
std::string mLabel;
......@@ -184,7 +194,8 @@ class Framebuffer final : public angle::ObserverInterface,
Framebuffer(const Caps &caps,
rx::GLImplFactory *factory,
FramebufferID id,
ContextID owningContextID);
ContextID owningContextID,
egl::ShareGroup *shareGroup);
// Constructor to build default framebuffers for a surface and context pair
Framebuffer(const Context *context, egl::Surface *surface, egl::Surface *readSurface);
// Constructor to build a fake default framebuffer when surfaceless
......@@ -415,8 +426,6 @@ class Framebuffer final : public angle::ObserverInterface,
static const FramebufferID kDefaultDrawFramebufferHandle;
rx::Serial serial() const { return mSerial; }
private:
bool detachResourceById(const Context *context, GLenum resourceType, GLuint resourceId);
bool detachMatchingAttachment(const Context *context,
......@@ -482,7 +491,6 @@ class Framebuffer final : public angle::ObserverInterface,
mFloat32ColorAttachmentBits.set(index, format->type == GL_FLOAT);
}
rx::Serial mSerial;
FramebufferState mState;
rx::FramebufferImpl *mImpl;
......
......@@ -351,11 +351,12 @@ Sync *SyncManager::getSync(GLuint handle) const
Framebuffer *FramebufferManager::AllocateNewObject(rx::GLImplFactory *factory,
FramebufferID handle,
const Caps &caps,
ContextID owningContextID)
ContextID owningContextID,
egl::ShareGroup *shareGroup)
{
// Make sure the caller isn't using a reserved handle.
ASSERT(handle != Framebuffer::kDefaultDrawFramebufferHandle);
return new Framebuffer(caps, factory, handle, owningContextID);
return new Framebuffer(caps, factory, handle, owningContextID, shareGroup);
}
// static
......
......@@ -19,14 +19,18 @@
namespace rx
{
class GLImplFactory;
}
} // namespace rx
namespace egl
{
class ShareGroup;
} // namespace egl
namespace gl
{
class Buffer;
struct Caps;
class Context;
class Sync;
class Framebuffer;
struct Limitations;
class MemoryObject;
......@@ -35,8 +39,9 @@ class Program;
class ProgramPipeline;
class Renderbuffer;
class Sampler;
class Shader;
class Semaphore;
class Shader;
class Sync;
class Texture;
template <typename HandleAllocatorType>
......@@ -276,15 +281,18 @@ class FramebufferManager
Framebuffer *checkFramebufferAllocation(rx::GLImplFactory *factory,
const Caps &caps,
FramebufferID handle,
ContextID owningContextID)
ContextID owningContextID,
egl::ShareGroup *shareGroup)
{
return checkObjectAllocation<const Caps &>(factory, handle, caps, owningContextID);
return checkObjectAllocation<const Caps &>(factory, handle, caps, owningContextID,
shareGroup);
}
static Framebuffer *AllocateNewObject(rx::GLImplFactory *factory,
FramebufferID handle,
const Caps &caps,
ContextID owningContextID);
ContextID owningContextID,
egl::ShareGroup *shareGroup);
static void DeleteObject(const Context *context, Framebuffer *framebuffer);
protected:
......
......@@ -20,7 +20,7 @@ namespace rx
class MockFramebufferImpl : public rx::FramebufferImpl
{
public:
MockFramebufferImpl() : rx::FramebufferImpl(gl::FramebufferState(1)) {}
MockFramebufferImpl() : rx::FramebufferImpl(gl::FramebufferState(1, rx::Serial())) {}
virtual ~MockFramebufferImpl() { destructor(); }
MOCK_METHOD3(discard, angle::Result(const gl::Context *, size_t, const GLenum *));
......
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