Commit 1e5499db by Jamie Madill Committed by Commit Bot

Refactor Signal utils into template classes.

This will allow us to pass on extra information to the receiving end, such as the specific texture levels that are dirty. BUG=angleproject:1635 Change-Id: Idb7ca1d625499e50e7712c458b694f6e9bfc0595 Reviewed-on: https://chromium-review.googlesource.com/453382 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 2b39659d
...@@ -34,7 +34,7 @@ namespace gl ...@@ -34,7 +34,7 @@ namespace gl
namespace namespace
{ {
void BindResourceChannel(ChannelBinding *binding, FramebufferAttachmentObject *resource) void BindResourceChannel(OnAttachmentDirtyBinding *binding, FramebufferAttachmentObject *resource)
{ {
binding->bind(resource ? resource->getDirtyChannel() : nullptr); binding->bind(resource ? resource->getDirtyChannel() : nullptr);
} }
...@@ -298,10 +298,10 @@ Framebuffer::Framebuffer(const Caps &caps, rx::GLImplFactory *factory, GLuint id ...@@ -298,10 +298,10 @@ Framebuffer::Framebuffer(const Caps &caps, rx::GLImplFactory *factory, GLuint id
ASSERT(mImpl != nullptr); ASSERT(mImpl != nullptr);
ASSERT(mState.mColorAttachments.size() == static_cast<size_t>(caps.maxColorAttachments)); ASSERT(mState.mColorAttachments.size() == static_cast<size_t>(caps.maxColorAttachments));
for (size_t colorIndex = 0; colorIndex < mState.mColorAttachments.size(); ++colorIndex) for (uint32_t colorIndex = 0;
colorIndex < static_cast<uint32_t>(mState.mColorAttachments.size()); ++colorIndex)
{ {
mDirtyColorAttachmentBindings.push_back(ChannelBinding( mDirtyColorAttachmentBindings.emplace_back(this, DIRTY_BIT_COLOR_ATTACHMENT_0 + colorIndex);
this, static_cast<SignalToken>(DIRTY_BIT_COLOR_ATTACHMENT_0 + colorIndex)));
} }
} }
...@@ -314,8 +314,7 @@ Framebuffer::Framebuffer(egl::Surface *surface) ...@@ -314,8 +314,7 @@ Framebuffer::Framebuffer(egl::Surface *surface)
mDirtyStencilAttachmentBinding(this, DIRTY_BIT_STENCIL_ATTACHMENT) mDirtyStencilAttachmentBinding(this, DIRTY_BIT_STENCIL_ATTACHMENT)
{ {
ASSERT(mImpl != nullptr); ASSERT(mImpl != nullptr);
mDirtyColorAttachmentBindings.push_back( mDirtyColorAttachmentBindings.emplace_back(this, DIRTY_BIT_COLOR_ATTACHMENT_0);
ChannelBinding(this, static_cast<SignalToken>(DIRTY_BIT_COLOR_ATTACHMENT_0)));
setAttachmentImpl(GL_FRAMEBUFFER_DEFAULT, GL_BACK, gl::ImageIndex::MakeInvalid(), surface); setAttachmentImpl(GL_FRAMEBUFFER_DEFAULT, GL_BACK, gl::ImageIndex::MakeInvalid(), surface);
...@@ -339,8 +338,7 @@ Framebuffer::Framebuffer(rx::GLImplFactory *factory) ...@@ -339,8 +338,7 @@ Framebuffer::Framebuffer(rx::GLImplFactory *factory)
mDirtyDepthAttachmentBinding(this, DIRTY_BIT_DEPTH_ATTACHMENT), mDirtyDepthAttachmentBinding(this, DIRTY_BIT_DEPTH_ATTACHMENT),
mDirtyStencilAttachmentBinding(this, DIRTY_BIT_STENCIL_ATTACHMENT) mDirtyStencilAttachmentBinding(this, DIRTY_BIT_STENCIL_ATTACHMENT)
{ {
mDirtyColorAttachmentBindings.push_back( mDirtyColorAttachmentBindings.emplace_back(this, DIRTY_BIT_COLOR_ATTACHMENT_0);
ChannelBinding(this, static_cast<SignalToken>(DIRTY_BIT_COLOR_ATTACHMENT_0)));
} }
Framebuffer::~Framebuffer() Framebuffer::~Framebuffer()
...@@ -1220,7 +1218,7 @@ void Framebuffer::syncState(const Context *context) ...@@ -1220,7 +1218,7 @@ void Framebuffer::syncState(const Context *context)
} }
} }
void Framebuffer::signal(SignalToken token) void Framebuffer::signal(uint32_t token)
{ {
// TOOD(jmadill): Make this only update individual attachments to do less work. // TOOD(jmadill): Make this only update individual attachments to do less work.
mCachedStatus.reset(); mCachedStatus.reset();
......
...@@ -115,7 +115,10 @@ class FramebufferState final : angle::NonCopyable ...@@ -115,7 +115,10 @@ class FramebufferState final : angle::NonCopyable
bool mWebGLDepthStencilConsistent; bool mWebGLDepthStencilConsistent;
}; };
class Framebuffer final : public LabeledObject, public angle::SignalReceiver using OnAttachmentDirtyReceiver = angle::SignalReceiver<>;
using OnAttachmentDirtyBinding = angle::ChannelBinding<>;
class Framebuffer final : public LabeledObject, public OnAttachmentDirtyReceiver
{ {
public: public:
// Constructor to build application-defined framebuffers // Constructor to build application-defined framebuffers
...@@ -239,7 +242,7 @@ class Framebuffer final : public LabeledObject, public angle::SignalReceiver ...@@ -239,7 +242,7 @@ class Framebuffer final : public LabeledObject, public angle::SignalReceiver
GLbitfield mask, GLbitfield mask,
GLenum filter); GLenum filter);
enum DirtyBitType enum DirtyBitType : uint32_t
{ {
DIRTY_BIT_COLOR_ATTACHMENT_0, DIRTY_BIT_COLOR_ATTACHMENT_0,
DIRTY_BIT_COLOR_ATTACHMENT_MAX = DIRTY_BIT_COLOR_ATTACHMENT_MAX =
...@@ -262,7 +265,7 @@ class Framebuffer final : public LabeledObject, public angle::SignalReceiver ...@@ -262,7 +265,7 @@ class Framebuffer final : public LabeledObject, public angle::SignalReceiver
void syncState(const Context *context); void syncState(const Context *context);
// angle::SignalReceiver implementation // angle::SignalReceiver implementation
void signal(angle::SignalToken token) override; void signal(uint32_t token) override;
bool formsRenderingFeedbackLoopWith(const State &state) const; bool formsRenderingFeedbackLoopWith(const State &state) const;
bool formsCopyingFeedbackLoopWith(GLuint copyTextureID, bool formsCopyingFeedbackLoopWith(GLuint copyTextureID,
...@@ -288,9 +291,9 @@ class Framebuffer final : public LabeledObject, public angle::SignalReceiver ...@@ -288,9 +291,9 @@ class Framebuffer final : public LabeledObject, public angle::SignalReceiver
GLuint mId; GLuint mId;
Optional<GLenum> mCachedStatus; Optional<GLenum> mCachedStatus;
std::vector<angle::ChannelBinding> mDirtyColorAttachmentBindings; std::vector<OnAttachmentDirtyBinding> mDirtyColorAttachmentBindings;
angle::ChannelBinding mDirtyDepthAttachmentBinding; OnAttachmentDirtyBinding mDirtyDepthAttachmentBinding;
angle::ChannelBinding mDirtyStencilAttachmentBinding; OnAttachmentDirtyBinding mDirtyStencilAttachmentBinding;
DirtyBits mDirtyBits; DirtyBits mDirtyBits;
}; };
......
...@@ -242,7 +242,7 @@ Error FramebufferAttachmentObject::getAttachmentRenderTarget( ...@@ -242,7 +242,7 @@ Error FramebufferAttachmentObject::getAttachmentRenderTarget(
return getAttachmentImpl()->getAttachmentRenderTarget(target, rtOut); return getAttachmentImpl()->getAttachmentRenderTarget(target, rtOut);
} }
angle::BroadcastChannel *FramebufferAttachmentObject::getDirtyChannel() angle::BroadcastChannel<> *FramebufferAttachmentObject::getDirtyChannel()
{ {
return &mDirtyChannel; return &mDirtyChannel;
} }
......
...@@ -168,12 +168,12 @@ class FramebufferAttachmentObject ...@@ -168,12 +168,12 @@ class FramebufferAttachmentObject
Error getAttachmentRenderTarget(const FramebufferAttachment::Target &target, Error getAttachmentRenderTarget(const FramebufferAttachment::Target &target,
rx::FramebufferAttachmentRenderTarget **rtOut) const; rx::FramebufferAttachmentRenderTarget **rtOut) const;
angle::BroadcastChannel *getDirtyChannel(); angle::BroadcastChannel<> *getDirtyChannel();
protected: protected:
virtual rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const = 0; virtual rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const = 0;
angle::BroadcastChannel mDirtyChannel; angle::BroadcastChannel<> mDirtyChannel;
}; };
inline Extents FramebufferAttachment::getSize() const inline Extents FramebufferAttachment::getSize() const
......
...@@ -143,7 +143,7 @@ class Buffer11::NativeStorage : public Buffer11::BufferStorage ...@@ -143,7 +143,7 @@ class Buffer11::NativeStorage : public Buffer11::BufferStorage
public: public:
NativeStorage(Renderer11 *renderer, NativeStorage(Renderer11 *renderer,
BufferUsage usage, BufferUsage usage,
const angle::BroadcastChannel *onStorageChanged); const angle::BroadcastChannel<> *onStorageChanged);
~NativeStorage() override; ~NativeStorage() override;
bool isMappable(GLbitfield access) const override; bool isMappable(GLbitfield access) const override;
...@@ -171,7 +171,7 @@ class Buffer11::NativeStorage : public Buffer11::BufferStorage ...@@ -171,7 +171,7 @@ class Buffer11::NativeStorage : public Buffer11::BufferStorage
void clearSRVs(); void clearSRVs();
ID3D11Buffer *mNativeStorage; ID3D11Buffer *mNativeStorage;
const angle::BroadcastChannel *mOnStorageChanged; const angle::BroadcastChannel<> *mOnStorageChanged;
std::map<DXGI_FORMAT, ID3D11ShaderResourceView *> mBufferResourceViews; std::map<DXGI_FORMAT, ID3D11ShaderResourceView *> mBufferResourceViews;
}; };
...@@ -902,12 +902,12 @@ void Buffer11::invalidateStaticData() ...@@ -902,12 +902,12 @@ void Buffer11::invalidateStaticData()
mStaticBroadcastChannel.signal(); mStaticBroadcastChannel.signal();
} }
angle::BroadcastChannel *Buffer11::getStaticBroadcastChannel() angle::BroadcastChannel<> *Buffer11::getStaticBroadcastChannel()
{ {
return &mStaticBroadcastChannel; return &mStaticBroadcastChannel;
} }
angle::BroadcastChannel *Buffer11::getDirectBroadcastChannel() angle::BroadcastChannel<> *Buffer11::getDirectBroadcastChannel()
{ {
return &mDirectBroadcastChannel; return &mDirectBroadcastChannel;
} }
...@@ -941,7 +941,7 @@ gl::Error Buffer11::BufferStorage::setData(const uint8_t *data, size_t offset, s ...@@ -941,7 +941,7 @@ gl::Error Buffer11::BufferStorage::setData(const uint8_t *data, size_t offset, s
Buffer11::NativeStorage::NativeStorage(Renderer11 *renderer, Buffer11::NativeStorage::NativeStorage(Renderer11 *renderer,
BufferUsage usage, BufferUsage usage,
const angle::BroadcastChannel *onStorageChanged) const angle::BroadcastChannel<> *onStorageChanged)
: BufferStorage(renderer, usage), mNativeStorage(nullptr), mOnStorageChanged(onStorageChanged) : BufferStorage(renderer, usage), mNativeStorage(nullptr), mOnStorageChanged(onStorageChanged)
{ {
} }
......
...@@ -103,8 +103,8 @@ class Buffer11 : public BufferD3D ...@@ -103,8 +103,8 @@ class Buffer11 : public BufferD3D
// We use two set of dirty events. Static buffers are marked dirty whenever // We use two set of dirty events. Static buffers are marked dirty whenever
// data changes, because they must be re-translated. Direct buffers only need to be // data changes, because they must be re-translated. Direct buffers only need to be
// updated when the underlying ID3D11Buffer pointer changes - hopefully far less often. // updated when the underlying ID3D11Buffer pointer changes - hopefully far less often.
angle::BroadcastChannel *getStaticBroadcastChannel(); angle::BroadcastChannel<> *getStaticBroadcastChannel();
angle::BroadcastChannel *getDirectBroadcastChannel(); angle::BroadcastChannel<> *getDirectBroadcastChannel();
private: private:
class BufferStorage; class BufferStorage;
...@@ -162,8 +162,8 @@ class Buffer11 : public BufferD3D ...@@ -162,8 +162,8 @@ class Buffer11 : public BufferD3D
size_t mConstantBufferStorageAdditionalSize; size_t mConstantBufferStorageAdditionalSize;
unsigned int mMaxConstantBufferLruCount; unsigned int mMaxConstantBufferLruCount;
angle::BroadcastChannel mStaticBroadcastChannel; angle::BroadcastChannel<> mStaticBroadcastChannel;
angle::BroadcastChannel mDirectBroadcastChannel; angle::BroadcastChannel<> mDirectBroadcastChannel;
}; };
} // namespace rx } // namespace rx
......
...@@ -54,7 +54,7 @@ gl::Error MarkAttachmentsDirty(const gl::FramebufferAttachment *attachment) ...@@ -54,7 +54,7 @@ gl::Error MarkAttachmentsDirty(const gl::FramebufferAttachment *attachment)
void UpdateCachedRenderTarget(const gl::FramebufferAttachment *attachment, void UpdateCachedRenderTarget(const gl::FramebufferAttachment *attachment,
RenderTarget11 *&cachedRenderTarget, RenderTarget11 *&cachedRenderTarget,
ChannelBinding *channelBinding) gl::OnAttachmentDirtyBinding *channelBinding)
{ {
RenderTarget11 *newRenderTarget = nullptr; RenderTarget11 *newRenderTarget = nullptr;
if (attachment) if (attachment)
...@@ -78,10 +78,10 @@ Framebuffer11::Framebuffer11(const gl::FramebufferState &data, Renderer11 *rende ...@@ -78,10 +78,10 @@ Framebuffer11::Framebuffer11(const gl::FramebufferState &data, Renderer11 *rende
{ {
ASSERT(mRenderer != nullptr); ASSERT(mRenderer != nullptr);
mCachedColorRenderTargets.fill(nullptr); mCachedColorRenderTargets.fill(nullptr);
for (size_t colorIndex = 0; colorIndex < data.getColorAttachments().size(); ++colorIndex) for (uint32_t colorIndex = 0;
colorIndex < static_cast<uint32_t>(data.getColorAttachments().size()); ++colorIndex)
{ {
mColorRenderTargetsDirty.push_back( mColorRenderTargetsDirty.emplace_back(this, colorIndex);
ChannelBinding(this, static_cast<SignalToken>(colorIndex)));
} }
} }
...@@ -413,9 +413,9 @@ void Framebuffer11::syncState(ContextImpl *contextImpl, const gl::Framebuffer::D ...@@ -413,9 +413,9 @@ void Framebuffer11::syncState(ContextImpl *contextImpl, const gl::Framebuffer::D
FramebufferD3D::syncState(contextImpl, dirtyBits); FramebufferD3D::syncState(contextImpl, dirtyBits);
} }
void Framebuffer11::signal(SignalToken token) void Framebuffer11::signal(uint32_t channelID)
{ {
if (token == gl::IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS) if (channelID == gl::IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS)
{ {
// Stencil is redundant in this case. // Stencil is redundant in this case.
mInternalDirtyBits.set(gl::Framebuffer::DIRTY_BIT_DEPTH_ATTACHMENT); mInternalDirtyBits.set(gl::Framebuffer::DIRTY_BIT_DEPTH_ATTACHMENT);
...@@ -423,8 +423,8 @@ void Framebuffer11::signal(SignalToken token) ...@@ -423,8 +423,8 @@ void Framebuffer11::signal(SignalToken token)
} }
else else
{ {
mInternalDirtyBits.set(gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0 + token); mInternalDirtyBits.set(gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0 + channelID);
mCachedColorRenderTargets[token] = nullptr; mCachedColorRenderTargets[channelID] = nullptr;
} }
} }
......
...@@ -17,7 +17,7 @@ namespace rx ...@@ -17,7 +17,7 @@ namespace rx
{ {
class Renderer11; class Renderer11;
class Framebuffer11 : public FramebufferD3D, public angle::SignalReceiver class Framebuffer11 : public FramebufferD3D, public angle::SignalReceiver<>
{ {
public: public:
Framebuffer11(const gl::FramebufferState &data, Renderer11 *renderer); Framebuffer11(const gl::FramebufferState &data, Renderer11 *renderer);
...@@ -44,7 +44,7 @@ class Framebuffer11 : public FramebufferD3D, public angle::SignalReceiver ...@@ -44,7 +44,7 @@ class Framebuffer11 : public FramebufferD3D, public angle::SignalReceiver
bool hasAnyInternalDirtyBit() const; bool hasAnyInternalDirtyBit() const;
void syncInternalState(ContextImpl *contextImpl); void syncInternalState(ContextImpl *contextImpl);
void signal(angle::SignalToken token) override; void signal(uint32_t channelID) override;
gl::Error getSamplePosition(size_t index, GLfloat *xy) const override; gl::Error getSamplePosition(size_t index, GLfloat *xy) const override;
...@@ -79,8 +79,8 @@ class Framebuffer11 : public FramebufferD3D, public angle::SignalReceiver ...@@ -79,8 +79,8 @@ class Framebuffer11 : public FramebufferD3D, public angle::SignalReceiver
RenderTargetArray mCachedColorRenderTargets; RenderTargetArray mCachedColorRenderTargets;
RenderTarget11 *mCachedDepthStencilRenderTarget; RenderTarget11 *mCachedDepthStencilRenderTarget;
std::vector<angle::ChannelBinding> mColorRenderTargetsDirty; std::vector<gl::OnAttachmentDirtyBinding> mColorRenderTargetsDirty;
angle::ChannelBinding mDepthStencilRenderTargetDirty; gl::OnAttachmentDirtyBinding mDepthStencilRenderTargetDirty;
gl::Framebuffer::DirtyBits mInternalDirtyBits; gl::Framebuffer::DirtyBits mInternalDirtyBits;
}; };
......
...@@ -35,12 +35,12 @@ class RenderTarget11 : public RenderTargetD3D ...@@ -35,12 +35,12 @@ class RenderTarget11 : public RenderTargetD3D
virtual unsigned int getSubresourceIndex() const = 0; virtual unsigned int getSubresourceIndex() const = 0;
void signalDirty() override; void signalDirty() override;
angle::BroadcastChannel *getBroadcastChannel() { return &mBroadcastChannel; } angle::BroadcastChannel<> *getBroadcastChannel() { return &mBroadcastChannel; }
const d3d11::Format &getFormatSet() const { return mFormatSet; } const d3d11::Format &getFormatSet() const { return mFormatSet; }
protected: protected:
angle::BroadcastChannel mBroadcastChannel; angle::BroadcastChannel<> mBroadcastChannel;
const d3d11::Format &mFormatSet; const d3d11::Format &mFormatSet;
}; };
......
...@@ -25,7 +25,7 @@ VertexArray11::VertexArray11(const gl::VertexArrayState &data) ...@@ -25,7 +25,7 @@ VertexArray11::VertexArray11(const gl::VertexArrayState &data)
{ {
for (size_t attribIndex = 0; attribIndex < mCurrentBuffers.size(); ++attribIndex) for (size_t attribIndex = 0; attribIndex < mCurrentBuffers.size(); ++attribIndex)
{ {
mOnBufferDataDirty.emplace_back(this, static_cast<SignalToken>(attribIndex)); mOnBufferDataDirty.emplace_back(this, static_cast<uint32_t>(attribIndex));
} }
} }
...@@ -112,7 +112,7 @@ void VertexArray11::updateVertexAttribStorage(size_t attribIndex) ...@@ -112,7 +112,7 @@ void VertexArray11::updateVertexAttribStorage(size_t attribIndex)
{ {
// Note that for static callbacks, promotion to a static buffer from a dynamic buffer means // Note that for static callbacks, promotion to a static buffer from a dynamic buffer means
// we need to tag dynamic buffers with static callbacks. // we need to tag dynamic buffers with static callbacks.
BroadcastChannel *newChannel = nullptr; BroadcastChannel<> *newChannel = nullptr;
if (newBuffer11 != nullptr) if (newBuffer11 != nullptr)
{ {
switch (newStorageType) switch (newStorageType)
...@@ -220,12 +220,12 @@ const std::vector<TranslatedAttribute> &VertexArray11::getTranslatedAttribs() co ...@@ -220,12 +220,12 @@ const std::vector<TranslatedAttribute> &VertexArray11::getTranslatedAttribs() co
return mTranslatedAttribs; return mTranslatedAttribs;
} }
void VertexArray11::signal(SignalToken token) void VertexArray11::signal(uint32_t channelID)
{ {
ASSERT(mAttributeStorageTypes[token] != VertexStorageType::CURRENT_VALUE); ASSERT(mAttributeStorageTypes[channelID] != VertexStorageType::CURRENT_VALUE);
// This can change a buffer's storage, we'll need to re-check. // This can change a buffer's storage, we'll need to re-check.
mAttribsToUpdate.set(token); mAttribsToUpdate.set(channelID);
} }
void VertexArray11::clearDirtyAndPromoteDynamicAttribs(const gl::State &state, GLsizei count) void VertexArray11::clearDirtyAndPromoteDynamicAttribs(const gl::State &state, GLsizei count)
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#ifndef LIBANGLE_RENDERER_D3D_D3D11_VERTEXARRAY11_H_ #ifndef LIBANGLE_RENDERER_D3D_D3D11_VERTEXARRAY11_H_
#define LIBANGLE_RENDERER_D3D_D3D11_VERTEXARRAY11_H_ #define LIBANGLE_RENDERER_D3D_D3D11_VERTEXARRAY11_H_
#include "libANGLE/Framebuffer.h"
#include "libANGLE/renderer/VertexArrayImpl.h" #include "libANGLE/renderer/VertexArrayImpl.h"
#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" #include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
#include "libANGLE/signal_utils.h" #include "libANGLE/signal_utils.h"
...@@ -17,7 +18,7 @@ namespace rx ...@@ -17,7 +18,7 @@ namespace rx
{ {
class Renderer11; class Renderer11;
class VertexArray11 : public VertexArrayImpl, public angle::SignalReceiver class VertexArray11 : public VertexArrayImpl, public angle::SignalReceiver<>
{ {
public: public:
VertexArray11(const gl::VertexArrayState &data); VertexArray11(const gl::VertexArrayState &data);
...@@ -36,7 +37,7 @@ class VertexArray11 : public VertexArrayImpl, public angle::SignalReceiver ...@@ -36,7 +37,7 @@ class VertexArray11 : public VertexArrayImpl, public angle::SignalReceiver
const std::vector<TranslatedAttribute> &getTranslatedAttribs() const; const std::vector<TranslatedAttribute> &getTranslatedAttribs() const;
// SignalReceiver implementation // SignalReceiver implementation
void signal(angle::SignalToken token) override; void signal(uint32_t channelID) override;
private: private:
void updateVertexAttribStorage(size_t attribIndex); void updateVertexAttribStorage(size_t attribIndex);
...@@ -57,7 +58,7 @@ class VertexArray11 : public VertexArrayImpl, public angle::SignalReceiver ...@@ -57,7 +58,7 @@ class VertexArray11 : public VertexArrayImpl, public angle::SignalReceiver
// We need to keep a safe pointer to the Buffer so we can attach the correct dirty callbacks. // We need to keep a safe pointer to the Buffer so we can attach the correct dirty callbacks.
std::vector<BindingPointer<gl::Buffer>> mCurrentBuffers; std::vector<BindingPointer<gl::Buffer>> mCurrentBuffers;
std::vector<angle::ChannelBinding> mOnBufferDataDirty; std::vector<gl::OnAttachmentDirtyBinding> mOnBufferDataDirty;
}; };
} // namespace rx } // namespace rx
......
//
// Copyright 2016 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// signal_utils:
// Helper classes for tracking dependent state changes between objects.
// These changes are signaled to the dependent class via channels.
#include "libANGLE/signal_utils.h"
#include <algorithm>
#include "common/debug.h"
namespace angle
{
BroadcastChannel::BroadcastChannel()
{
}
BroadcastChannel::~BroadcastChannel()
{
reset();
}
void BroadcastChannel::addReceiver(ChannelBinding *receiver)
{
ASSERT(std::find(mReceivers.begin(), mReceivers.end(), receiver) == mReceivers.end());
mReceivers.push_back(receiver);
}
void BroadcastChannel::removeReceiver(ChannelBinding *receiver)
{
auto iter = std::find(mReceivers.begin(), mReceivers.end(), receiver);
ASSERT(iter != mReceivers.end());
mReceivers.erase(iter);
}
void BroadcastChannel::signal() const
{
if (mReceivers.empty())
return;
for (const auto *receiver : mReceivers)
{
receiver->signal();
}
}
void BroadcastChannel::reset()
{
for (auto receiver : mReceivers)
{
receiver->onChannelClosed();
}
mReceivers.clear();
}
ChannelBinding::ChannelBinding(SignalReceiver *receiver, SignalToken token)
: mChannel(nullptr), mReceiver(receiver), mToken(token)
{
ASSERT(receiver);
}
ChannelBinding::~ChannelBinding()
{
reset();
}
void ChannelBinding::bind(BroadcastChannel *channel)
{
ASSERT(mReceiver);
if (mChannel)
{
mChannel->removeReceiver(this);
}
mChannel = channel;
if (mChannel)
{
mChannel->addReceiver(this);
}
}
void ChannelBinding::reset()
{
bind(nullptr);
}
void ChannelBinding::signal() const
{
mReceiver->signal(mToken);
}
void ChannelBinding::onChannelClosed()
{
mChannel = nullptr;
}
} // namespace angle
...@@ -13,62 +13,165 @@ ...@@ -13,62 +13,165 @@
#include <set> #include <set>
#include "common/angleutils.h" #include "common/angleutils.h"
#include "common/debug.h"
namespace angle namespace angle
{ {
// Message token passed to the receiver;
using SignalToken = uint32_t;
// Interface that the depending class inherits from. // Interface that the depending class inherits from.
template <typename ChannelID = uint32_t, typename... MessageT>
class SignalReceiver class SignalReceiver
{ {
public: public:
virtual ~SignalReceiver() = default; virtual ~SignalReceiver() = default;
virtual void signal(SignalToken token) = 0; virtual void signal(ChannelID channelID, MessageT... message) = 0;
}; };
template <typename ChannelID, typename... MessageT>
class ChannelBinding; class ChannelBinding;
// The host class owns the channel. It uses the channel to fire signals to the receiver. // The host class owns the channel. It uses the channel to fire signals to the receiver.
template <typename ChannelID = uint32_t, typename... MessageT>
class BroadcastChannel final : NonCopyable class BroadcastChannel final : NonCopyable
{ {
public: public:
BroadcastChannel(); BroadcastChannel();
~BroadcastChannel(); ~BroadcastChannel();
void signal() const; void signal(MessageT... message) const;
void reset(); void reset();
private: private:
// Only the ChannelBinding class should add or remove receivers. // Only the ChannelBinding class should add or remove receivers.
friend class ChannelBinding; friend class ChannelBinding<ChannelID, MessageT...>;
void addReceiver(ChannelBinding *receiver); void addReceiver(ChannelBinding<ChannelID, MessageT...> *receiver);
void removeReceiver(ChannelBinding *receiver); void removeReceiver(ChannelBinding<ChannelID, MessageT...> *receiver);
std::vector<ChannelBinding *> mReceivers; std::vector<ChannelBinding<ChannelID, MessageT...> *> mReceivers;
}; };
template <typename ChannelID, typename... MessageT>
BroadcastChannel<ChannelID, MessageT...>::BroadcastChannel()
{
}
template <typename ChannelID, typename... MessageT>
BroadcastChannel<ChannelID, MessageT...>::~BroadcastChannel()
{
reset();
}
template <typename ChannelID, typename... MessageT>
void BroadcastChannel<ChannelID, MessageT...>::addReceiver(
ChannelBinding<ChannelID, MessageT...> *receiver)
{
ASSERT(std::find(mReceivers.begin(), mReceivers.end(), receiver) == mReceivers.end());
mReceivers.push_back(receiver);
}
template <typename ChannelID, typename... MessageT>
void BroadcastChannel<ChannelID, MessageT...>::removeReceiver(
ChannelBinding<ChannelID, MessageT...> *receiver)
{
auto iter = std::find(mReceivers.begin(), mReceivers.end(), receiver);
ASSERT(iter != mReceivers.end());
mReceivers.erase(iter);
}
template <typename ChannelID, typename... MessageT>
void BroadcastChannel<ChannelID, MessageT...>::signal(MessageT... message) const
{
if (mReceivers.empty())
return;
for (const auto *receiver : mReceivers)
{
receiver->signal(message...);
}
}
template <typename ChannelID, typename... MessageT>
void BroadcastChannel<ChannelID, MessageT...>::reset()
{
for (auto receiver : mReceivers)
{
receiver->onChannelClosed();
}
mReceivers.clear();
}
// The dependent class keeps bindings to the host's BroadcastChannel. // The dependent class keeps bindings to the host's BroadcastChannel.
template <typename ChannelID = uint32_t, typename... MessageT>
class ChannelBinding final class ChannelBinding final
{ {
public: public:
ChannelBinding(SignalReceiver *receiver, SignalToken token); ChannelBinding(SignalReceiver<ChannelID, MessageT...> *receiver, ChannelID channelID);
~ChannelBinding(); ~ChannelBinding();
ChannelBinding(const ChannelBinding &other) = default; ChannelBinding(const ChannelBinding &other) = default;
ChannelBinding &operator=(const ChannelBinding &other) = default; ChannelBinding &operator=(const ChannelBinding &other) = default;
void bind(BroadcastChannel *channel); void bind(BroadcastChannel<ChannelID, MessageT...> *channel);
void reset(); void reset();
void signal() const; void signal(MessageT... message) const;
void onChannelClosed(); void onChannelClosed();
private: private:
BroadcastChannel *mChannel; BroadcastChannel<ChannelID, MessageT...> *mChannel;
SignalReceiver *mReceiver; SignalReceiver<ChannelID, MessageT...> *mReceiver;
SignalToken mToken; ChannelID mChannelID;
}; };
template <typename ChannelID, typename... MessageT>
ChannelBinding<ChannelID, MessageT...>::ChannelBinding(
SignalReceiver<ChannelID, MessageT...> *receiver,
ChannelID channelID)
: mChannel(nullptr), mReceiver(receiver), mChannelID(channelID)
{
ASSERT(receiver);
}
template <typename ChannelID, typename... MessageT>
ChannelBinding<ChannelID, MessageT...>::~ChannelBinding()
{
reset();
}
template <typename ChannelID, typename... MessageT>
void ChannelBinding<ChannelID, MessageT...>::bind(BroadcastChannel<ChannelID, MessageT...> *channel)
{
ASSERT(mReceiver);
if (mChannel)
{
mChannel->removeReceiver(this);
}
mChannel = channel;
if (mChannel)
{
mChannel->addReceiver(this);
}
}
template <typename ChannelID, typename... MessageT>
void ChannelBinding<ChannelID, MessageT...>::reset()
{
bind(nullptr);
}
template <typename ChannelID, typename... MessageT>
void ChannelBinding<ChannelID, MessageT...>::signal(MessageT... message) const
{
mReceiver->signal(mChannelID, message...);
}
template <typename ChannelID, typename... MessageT>
void ChannelBinding<ChannelID, MessageT...>::onChannelClosed()
{
mChannel = nullptr;
}
} // namespace angle } // namespace angle
#endif // LIBANGLE_SIGNAL_UTILS_H_ #endif // LIBANGLE_SIGNAL_UTILS_H_
...@@ -16,18 +16,18 @@ using namespace testing; ...@@ -16,18 +16,18 @@ using namespace testing;
namespace namespace
{ {
struct SignalThing : public SignalReceiver struct SignalThing : public SignalReceiver<>
{ {
void signal(SignalToken token) override { wasSignaled = true; } void signal(uint32_t channelID) override { wasSignaled = true; }
bool wasSignaled = false; bool wasSignaled = false;
}; };
// Test that broadcast signals work. // Test that broadcast signals work.
TEST(SignalTest, BroadcastSignals) TEST(SignalTest, BroadcastSignals)
{ {
BroadcastChannel channel; BroadcastChannel<> channel;
SignalThing thing; SignalThing thing;
ChannelBinding binding(&thing, 0u); ChannelBinding<> binding(&thing, 0u);
binding.bind(&channel); binding.bind(&channel);
ASSERT_FALSE(thing.wasSignaled); ASSERT_FALSE(thing.wasSignaled);
......
...@@ -248,7 +248,6 @@ ...@@ -248,7 +248,6 @@
'libANGLE/renderer/load_functions_table_autogen.cpp', 'libANGLE/renderer/load_functions_table_autogen.cpp',
'libANGLE/renderer/renderer_utils.cpp', 'libANGLE/renderer/renderer_utils.cpp',
'libANGLE/renderer/renderer_utils.h', 'libANGLE/renderer/renderer_utils.h',
'libANGLE/signal_utils.cpp',
'libANGLE/signal_utils.h', 'libANGLE/signal_utils.h',
'libANGLE/validationEGL.cpp', 'libANGLE/validationEGL.cpp',
'libANGLE/validationEGL.h', 'libANGLE/validationEGL.h',
......
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