Commit ea84f6ff by Jamie Madill Committed by Commit Bot

Pass Context to Framebuffer11 dirty callback.

This allows us to call StateManager11::invalidateRenderTarget from the Framebuffer11::signal function, which will then trigger state refresh on the next draw call. This requires passing Context through a few more Renderbuffer methods, and reorganizing the RenderTarget signalling so that it doesn't signal dirty in the destructor. Instead they are signaled as they are destroyed in the containing classes. BUG=angleproject:2151 Change-Id: I4cf575e4a01b48275ff78d75bc55b2d1fced591d Reviewed-on: https://chromium-review.googlesource.com/673139 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarFrank Henigman <fjhenigman@chromium.org>
parent 8ec383e6
......@@ -57,7 +57,7 @@ TEST(ImageTest, RefCounting)
gl::Renderbuffer *renderbuffer = new gl::Renderbuffer(renderbufferImpl, 1);
renderbuffer->addRef();
EXPECT_CALL(*renderbufferImpl, setStorageEGLImageTarget(_))
EXPECT_CALL(*renderbufferImpl, setStorageEGLImageTarget(_, _))
.WillOnce(Return(gl::NoError()))
.RetiresOnSaturation();
EXPECT_FALSE(renderbuffer->setStorageEGLImageTarget(nullptr, image).isError());
......
......@@ -32,7 +32,14 @@ Renderbuffer::Renderbuffer(rx::RenderbufferImpl *impl, GLuint id)
Error Renderbuffer::onDestroy(const Context *context)
{
return orphanImages(context);
ANGLE_TRY(orphanImages(context));
if (mRenderbuffer)
{
ANGLE_TRY(mRenderbuffer->onDestroy(context));
}
return NoError();
}
Renderbuffer::~Renderbuffer()
......@@ -57,7 +64,7 @@ Error Renderbuffer::setStorage(const Context *context,
{
ANGLE_TRY(orphanImages(context));
ANGLE_TRY(mRenderbuffer->setStorage(internalformat, width, height));
ANGLE_TRY(mRenderbuffer->setStorage(context, internalformat, width, height));
mWidth = static_cast<GLsizei>(width);
mHeight = static_cast<GLsizei>(height);
......@@ -77,7 +84,8 @@ Error Renderbuffer::setStorageMultisample(const Context *context,
{
ANGLE_TRY(orphanImages(context));
ANGLE_TRY(mRenderbuffer->setStorageMultisample(samples, internalformat, width, height));
ANGLE_TRY(
mRenderbuffer->setStorageMultisample(context, samples, internalformat, width, height));
mWidth = static_cast<GLsizei>(width);
mHeight = static_cast<GLsizei>(height);
......@@ -93,7 +101,7 @@ Error Renderbuffer::setStorageEGLImageTarget(const Context *context, egl::Image
{
ANGLE_TRY(orphanImages(context));
ANGLE_TRY(mRenderbuffer->setStorageEGLImageTarget(image));
ANGLE_TRY(mRenderbuffer->setStorageEGLImageTarget(context, image));
setTargetImage(context, image);
......
......@@ -27,10 +27,18 @@ class RenderbufferImpl : public FramebufferAttachmentObjectImpl
public:
RenderbufferImpl() {}
virtual ~RenderbufferImpl() {}
virtual gl::Error setStorage(GLenum internalformat, size_t width, size_t height) = 0;
virtual gl::Error setStorageMultisample(size_t samples, GLenum internalformat, size_t width, size_t height) = 0;
virtual gl::Error setStorageEGLImageTarget(egl::Image *image) = 0;
virtual gl::Error onDestroy(const gl::Context *context) { return gl::NoError(); }
virtual gl::Error setStorage(const gl::Context *context,
GLenum internalformat,
size_t width,
size_t height) = 0;
virtual gl::Error setStorageMultisample(const gl::Context *context,
size_t samples,
GLenum internalformat,
size_t width,
size_t height) = 0;
virtual gl::Error setStorageEGLImageTarget(const gl::Context *context, egl::Image *image) = 0;
};
}
......
......@@ -21,9 +21,10 @@ class MockRenderbufferImpl : public RenderbufferImpl
{
public:
virtual ~MockRenderbufferImpl() { destructor(); }
MOCK_METHOD3(setStorage, gl::Error(GLenum, size_t, size_t));
MOCK_METHOD4(setStorageMultisample, gl::Error(size_t, GLenum, size_t, size_t));
MOCK_METHOD1(setStorageEGLImageTarget, gl::Error(egl::Image *));
MOCK_METHOD4(setStorage, gl::Error(const gl::Context *, GLenum, size_t, size_t));
MOCK_METHOD5(setStorageMultisample,
gl::Error(const gl::Context *, size_t, GLenum, size_t, size_t));
MOCK_METHOD2(setStorageEGLImageTarget, gl::Error(const gl::Context *, egl::Image *));
MOCK_METHOD4(getAttachmentRenderTarget,
gl::Error(const gl::Context *,
......
......@@ -80,7 +80,7 @@ gl::Error EGLImageD3D::copyToLocalRendertarget(const gl::Context *context)
ANGLE_TRY(getRenderTarget(context, &curRenderTarget));
// This only currently applies do D3D11, where it invalidates FBOs with this Image attached.
curRenderTarget->signalDirty();
curRenderTarget->signalDirty(context);
return mRenderer->createRenderTargetCopy(curRenderTarget, &mRenderTarget);
}
......
......@@ -35,7 +35,7 @@ class RenderTargetD3D : public FramebufferAttachmentRenderTarget
static unsigned int issueSerials(unsigned int count);
// Only currently applies to D3D11.
virtual void signalDirty() {}
virtual void signalDirty(const gl::Context *context) {}
private:
const unsigned int mSerial;
......
......@@ -27,12 +27,25 @@ RenderbufferD3D::~RenderbufferD3D()
mImage = nullptr;
}
gl::Error RenderbufferD3D::setStorage(GLenum internalformat, size_t width, size_t height)
gl::Error RenderbufferD3D::onDestroy(const gl::Context *context)
{
return setStorageMultisample(0, internalformat, width, height);
deleteRenderTarget(context);
return gl::NoError();
}
gl::Error RenderbufferD3D::setStorageMultisample(size_t samples, GLenum internalformat, size_t width, size_t height)
gl::Error RenderbufferD3D::setStorage(const gl::Context *context,
GLenum internalformat,
size_t width,
size_t height)
{
return setStorageMultisample(context, 0, internalformat, width, height);
}
gl::Error RenderbufferD3D::setStorageMultisample(const gl::Context *context,
size_t samples,
GLenum internalformat,
size_t width,
size_t height)
{
// If the renderbuffer parameters are queried, the calling function
// will expect one of the valid renderbuffer formats for use in
......@@ -60,17 +73,17 @@ gl::Error RenderbufferD3D::setStorageMultisample(size_t samples, GLenum internal
ANGLE_TRY(mRenderer->createRenderTarget(static_cast<int>(width), static_cast<int>(height),
creationFormat, static_cast<GLsizei>(samples), &newRT));
SafeDelete(mRenderTarget);
deleteRenderTarget(context);
mImage = nullptr;
mRenderTarget = newRT;
return gl::NoError();
}
gl::Error RenderbufferD3D::setStorageEGLImageTarget(egl::Image *image)
gl::Error RenderbufferD3D::setStorageEGLImageTarget(const gl::Context *context, egl::Image *image)
{
mImage = GetImplAs<EGLImageD3D>(image);
SafeDelete(mRenderTarget);
deleteRenderTarget(context);
return gl::NoError();
}
......@@ -97,4 +110,12 @@ gl::Error RenderbufferD3D::getAttachmentRenderTarget(const gl::Context *context,
return getRenderTarget(context, reinterpret_cast<RenderTargetD3D **>(rtOut));
}
void RenderbufferD3D::deleteRenderTarget(const gl::Context *context)
{
if (mRenderTarget)
{
mRenderTarget->signalDirty(context);
SafeDelete(mRenderTarget);
}
}
} // namespace rx
......@@ -27,12 +27,18 @@ class RenderbufferD3D : public RenderbufferImpl
RenderbufferD3D(RendererD3D *renderer);
virtual ~RenderbufferD3D();
gl::Error setStorage(GLenum internalformat, size_t width, size_t height) override;
gl::Error setStorageMultisample(size_t samples,
gl::Error onDestroy(const gl::Context *context) override;
gl::Error setStorage(const gl::Context *context,
GLenum internalformat,
size_t width,
size_t height) override;
gl::Error setStorageMultisample(const gl::Context *context,
size_t samples,
GLenum internalformat,
size_t width,
size_t height) override;
gl::Error setStorageEGLImageTarget(egl::Image *image) override;
gl::Error setStorageEGLImageTarget(const gl::Context *context, egl::Image *image) override;
gl::Error getRenderTarget(const gl::Context *context, RenderTargetD3D **outRenderTarget);
gl::Error getAttachmentRenderTarget(const gl::Context *context,
......@@ -41,6 +47,8 @@ class RenderbufferD3D : public RenderbufferImpl
FramebufferAttachmentRenderTarget **rtOut) override;
private:
void deleteRenderTarget(const gl::Context *context);
RendererD3D *mRenderer;
RenderTargetD3D *mRenderTarget;
EGLImageD3D *mImage;
......
......@@ -430,7 +430,7 @@ gl::Error TextureD3D::generateMipmap(const gl::Context *context)
// Switch to using the mipmapped texture.
TextureStorage *textureStorage = nullptr;
ANGLE_TRY(getNativeTexture(context, &textureStorage));
ANGLE_TRY(textureStorage->useLevelZeroWorkaroundTexture(false));
ANGLE_TRY(textureStorage->useLevelZeroWorkaroundTexture(context, false));
}
// Set up proper mipmap chain in our Image array.
......
......@@ -63,7 +63,8 @@ class TextureStorage : angle::NonCopyable
const uint8_t *pixelData) = 0;
// This is a no-op for most implementations of TextureStorage. Some (e.g. TextureStorage11_2D) might override it.
virtual gl::Error useLevelZeroWorkaroundTexture(bool useLevelZeroTexture)
virtual gl::Error useLevelZeroWorkaroundTexture(const gl::Context *context,
bool useLevelZeroTexture)
{
return gl::NoError();
}
......
......@@ -446,7 +446,7 @@ void Framebuffer11::syncState(const gl::Context *context,
}
}
void Framebuffer11::signal(size_t channelID)
void Framebuffer11::signal(size_t channelID, const gl::Context *context)
{
if (channelID == gl::IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS)
{
......
......@@ -52,7 +52,7 @@ class Framebuffer11 : public FramebufferD3D, public OnRenderTargetDirtyReceiver
bool hasAnyInternalDirtyBit() const;
void syncInternalState(const gl::Context *context);
void signal(size_t channelID) override;
void signal(size_t channelID, const gl::Context *context) override;
gl::Error getSamplePosition(size_t index, GLfloat *xy) const override;
......
......@@ -200,12 +200,12 @@ RenderTarget11::RenderTarget11(const d3d11::Format &formatSet) : mFormatSet(form
RenderTarget11::~RenderTarget11()
{
signalDirty();
ASSERT(mBroadcastChannel.empty());
}
void RenderTarget11::signalDirty()
void RenderTarget11::signalDirty(const gl::Context *context)
{
mBroadcastChannel.signal();
mBroadcastChannel.signal(context);
// Clear the list. We can't do this in the receiver because it would mutate during iteration.
mBroadcastChannel.reset();
......
......@@ -34,7 +34,7 @@ class RenderTarget11 : public RenderTargetD3D
virtual unsigned int getSubresourceIndex() const = 0;
void signalDirty() override;
void signalDirty(const gl::Context *context) override;
OnRenderTargetDirtyChannel *getBroadcastChannel() { return &mBroadcastChannel; }
const d3d11::Format &getFormatSet() const { return mFormatSet; }
......
......@@ -110,6 +110,8 @@ SwapChain11::~SwapChain11()
void SwapChain11::release()
{
// TODO(jmadill): Should probably signal that the RenderTarget is dirty.
SafeRelease(mSwapChain1);
SafeRelease(mSwapChain);
SafeRelease(mKeyedMutex);
......
......@@ -209,7 +209,8 @@ class TextureStorage11_2D : public TextureStorage11
const gl::ImageIndex &index,
Image11 *incomingImage) override;
gl::Error useLevelZeroWorkaroundTexture(bool useLevelZeroTexture) override;
gl::Error useLevelZeroWorkaroundTexture(const gl::Context *context,
bool useLevelZeroTexture) override;
protected:
gl::Error getSwizzleTexture(const TextureHelper11 **outTexture) override;
......@@ -323,7 +324,8 @@ class TextureStorage11_EGLImage final : public TextureStorage11
const gl::ImageIndex &index,
Image11 *incomingImage) override;
gl::Error useLevelZeroWorkaroundTexture(bool useLevelZeroTexture) override;
gl::Error useLevelZeroWorkaroundTexture(const gl::Context *context,
bool useLevelZeroTexture) override;
protected:
gl::Error getSwizzleTexture(const TextureHelper11 **outTexture) override;
......@@ -377,7 +379,8 @@ class TextureStorage11_Cube : public TextureStorage11
const gl::ImageIndex &index,
Image11 *incomingImage) override;
gl::Error useLevelZeroWorkaroundTexture(bool useLevelZeroTexture) override;
gl::Error useLevelZeroWorkaroundTexture(const gl::Context *context,
bool useLevelZeroTexture) override;
protected:
gl::Error getSwizzleTexture(const TextureHelper11 **outTexture) override;
......
......@@ -401,9 +401,9 @@ using OnBufferDataDirtyChannel = angle::BroadcastChannel<size_t, const gl::Cont
using OnBufferDataDirtyReceiver = angle::SignalReceiver<size_t, const gl::Context *>;
// Used for state change notifications between RenderTarget11 and Framebuffer11.
using OnRenderTargetDirtyBinding = angle::ChannelBinding<size_t>;
using OnRenderTargetDirtyChannel = angle::BroadcastChannel<size_t>;
using OnRenderTargetDirtyReceiver = angle::SignalReceiver<size_t>;
using OnRenderTargetDirtyBinding = angle::ChannelBinding<size_t, const gl::Context *>;
using OnRenderTargetDirtyChannel = angle::BroadcastChannel<size_t, const gl::Context *>;
using OnRenderTargetDirtyReceiver = angle::SignalReceiver<size_t, const gl::Context *>;
} // namespace rx
......
......@@ -39,7 +39,10 @@ RenderbufferGL::~RenderbufferGL()
mRenderbufferID = 0;
}
gl::Error RenderbufferGL::setStorage(GLenum internalformat, size_t width, size_t height)
gl::Error RenderbufferGL::setStorage(const gl::Context *context,
GLenum internalformat,
size_t width,
size_t height)
{
mStateManager->bindRenderbuffer(GL_RENDERBUFFER, mRenderbufferID);
......@@ -51,7 +54,11 @@ gl::Error RenderbufferGL::setStorage(GLenum internalformat, size_t width, size_t
return gl::NoError();
}
gl::Error RenderbufferGL::setStorageMultisample(size_t samples, GLenum internalformat, size_t width, size_t height)
gl::Error RenderbufferGL::setStorageMultisample(const gl::Context *context,
size_t samples,
GLenum internalformat,
size_t width,
size_t height)
{
mStateManager->bindRenderbuffer(GL_RENDERBUFFER, mRenderbufferID);
......@@ -82,7 +89,7 @@ gl::Error RenderbufferGL::setStorageMultisample(size_t samples, GLenum internalf
return gl::NoError();
}
gl::Error RenderbufferGL::setStorageEGLImageTarget(egl::Image *image)
gl::Error RenderbufferGL::setStorageEGLImageTarget(const gl::Context *context, egl::Image *image)
{
UNIMPLEMENTED();
return gl::InternalError();
......
......@@ -32,9 +32,17 @@ class RenderbufferGL : public RenderbufferImpl
const gl::TextureCapsMap &textureCaps);
~RenderbufferGL() override;
virtual gl::Error setStorage(GLenum internalformat, size_t width, size_t height) override;
virtual gl::Error setStorageMultisample(size_t samples, GLenum internalformat, size_t width, size_t height) override;
virtual gl::Error setStorageEGLImageTarget(egl::Image *image) override;
virtual gl::Error setStorage(const gl::Context *context,
GLenum internalformat,
size_t width,
size_t height) override;
virtual gl::Error setStorageMultisample(const gl::Context *context,
size_t samples,
GLenum internalformat,
size_t width,
size_t height) override;
virtual gl::Error setStorageEGLImageTarget(const gl::Context *context,
egl::Image *image) override;
GLuint getRenderbufferID() const;
......
......@@ -22,12 +22,16 @@ RenderbufferNULL::~RenderbufferNULL()
{
}
gl::Error RenderbufferNULL::setStorage(GLenum internalformat, size_t width, size_t height)
gl::Error RenderbufferNULL::setStorage(const gl::Context *context,
GLenum internalformat,
size_t width,
size_t height)
{
return gl::NoError();
}
gl::Error RenderbufferNULL::setStorageMultisample(size_t samples,
gl::Error RenderbufferNULL::setStorageMultisample(const gl::Context *context,
size_t samples,
GLenum internalformat,
size_t width,
size_t height)
......@@ -35,7 +39,7 @@ gl::Error RenderbufferNULL::setStorageMultisample(size_t samples,
return gl::NoError();
}
gl::Error RenderbufferNULL::setStorageEGLImageTarget(egl::Image *image)
gl::Error RenderbufferNULL::setStorageEGLImageTarget(const gl::Context *context, egl::Image *image)
{
return gl::NoError();
}
......
......@@ -21,12 +21,16 @@ class RenderbufferNULL : public RenderbufferImpl
RenderbufferNULL();
~RenderbufferNULL() override;
gl::Error setStorage(GLenum internalformat, size_t width, size_t height) override;
gl::Error setStorageMultisample(size_t samples,
gl::Error setStorage(const gl::Context *context,
GLenum internalformat,
size_t width,
size_t height) override;
gl::Error setStorageMultisample(const gl::Context *context,
size_t samples,
GLenum internalformat,
size_t width,
size_t height) override;
gl::Error setStorageEGLImageTarget(egl::Image *image) override;
gl::Error setStorageEGLImageTarget(const gl::Context *context, egl::Image *image) override;
};
} // namespace rx
......
......@@ -22,13 +22,17 @@ RenderbufferVk::~RenderbufferVk()
{
}
gl::Error RenderbufferVk::setStorage(GLenum internalformat, size_t width, size_t height)
gl::Error RenderbufferVk::setStorage(const gl::Context *context,
GLenum internalformat,
size_t width,
size_t height)
{
UNIMPLEMENTED();
return gl::InternalError();
}
gl::Error RenderbufferVk::setStorageMultisample(size_t samples,
gl::Error RenderbufferVk::setStorageMultisample(const gl::Context *context,
size_t samples,
GLenum internalformat,
size_t width,
size_t height)
......@@ -37,7 +41,7 @@ gl::Error RenderbufferVk::setStorageMultisample(size_t samples,
return gl::InternalError();
}
gl::Error RenderbufferVk::setStorageEGLImageTarget(egl::Image *image)
gl::Error RenderbufferVk::setStorageEGLImageTarget(const gl::Context *context, egl::Image *image)
{
UNIMPLEMENTED();
return gl::InternalError();
......
......@@ -21,12 +21,16 @@ class RenderbufferVk : public RenderbufferImpl
RenderbufferVk();
~RenderbufferVk() override;
gl::Error setStorage(GLenum internalformat, size_t width, size_t height) override;
gl::Error setStorageMultisample(size_t samples,
gl::Error setStorage(const gl::Context *context,
GLenum internalformat,
size_t width,
size_t height) override;
gl::Error setStorageMultisample(const gl::Context *context,
size_t samples,
GLenum internalformat,
size_t width,
size_t height) override;
gl::Error setStorageEGLImageTarget(egl::Image *image) override;
gl::Error setStorageEGLImageTarget(const gl::Context *context, egl::Image *image) override;
gl::Error getAttachmentRenderTarget(const gl::Context *context,
GLenum binding,
......
......@@ -44,6 +44,8 @@ class BroadcastChannel final : NonCopyable
void reset();
bool empty() const;
private:
// Only the ChannelBinding class should add or remove receivers.
friend class ChannelBinding<ChannelID, MessageT...>;
......@@ -103,6 +105,12 @@ void BroadcastChannel<ChannelID, MessageT...>::reset()
mReceivers.clear();
}
template <typename ChannelID, typename... MessageT>
bool BroadcastChannel<ChannelID, MessageT...>::empty() const
{
return mReceivers.empty();
}
// The dependent class keeps bindings to the host's BroadcastChannel.
template <typename ChannelID = uint32_t, typename... MessageT>
class ChannelBinding final
......
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