Commit 36f34243 by Jamie Madill Committed by Commit Bot

Buffer11: Cache latest buffer storage.

This saves needing to scan the list of buffers every time we query the latest buffer storage. Should slightly improve speed. BUG=angleproject:1155 Change-Id: I6be8457aca1ee5aa871090241e6f67ae16b094a5 Reviewed-on: https://chromium-review.googlesource.com/761242Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 8d6af086
......@@ -295,6 +295,7 @@ Buffer11::Buffer11(const gl::BufferState &state, Renderer11 *renderer)
mSize(0),
mMappedStorage(nullptr),
mBufferStorages({}),
mLatestBufferStorage(nullptr),
mDeallocThresholds({}),
mIdleness({}),
mConstantBufferStorageAdditionalSize(0),
......@@ -398,7 +399,7 @@ gl::Error Buffer11::setSubData(const gl::Context *context,
}
ANGLE_TRY(writeBuffer->setData(static_cast<const uint8_t *>(data), offset, size));
writeBuffer->setDataRevision(writeBuffer->getDataRevision() + 1);
onStorageUpdate(writeBuffer);
// Notify any vertex arrays that we have dirty data.
// TODO(jmadill): Use a more fine grained notification for data updates.
......@@ -465,7 +466,7 @@ gl::Error Buffer11::copySubData(const gl::Context *context,
CopyResult copyResult = CopyResult::NOT_RECREATED;
ANGLE_TRY_RESULT(copyDest->copyFromStorage(context, copySource, sourceOffset, size, destOffset),
copyResult);
copyDest->setDataRevision(copyDest->getDataRevision() + 1);
onStorageUpdate(copyDest);
mSize = std::max<size_t>(mSize, destOffset + size);
invalidateStaticData(context);
......@@ -513,7 +514,7 @@ gl::Error Buffer11::mapRange(const gl::Context *context,
if ((access & GL_MAP_WRITE_BIT) > 0)
{
// Update the data revision immediately, since the data might be changed at any time
mMappedStorage->setDataRevision(mMappedStorage->getDataRevision() + 1);
onStorageUpdate(mMappedStorage);
invalidateStaticData(context);
}
......@@ -545,7 +546,7 @@ gl::Error Buffer11::markTransformFeedbackUsage(const gl::Context *context)
if (transformFeedbackStorage)
{
transformFeedbackStorage->setDataRevision(transformFeedbackStorage->getDataRevision() + 1);
onStorageUpdate(transformFeedbackStorage);
}
invalidateStaticData(context);
......@@ -694,12 +695,9 @@ gl::Error Buffer11::packPixels(const gl::Context *context,
PackStorage *packStorage = nullptr;
ANGLE_TRY_RESULT(getPackStorage(context), packStorage);
BufferStorage *latestStorage = nullptr;
ANGLE_TRY_RESULT(getLatestBufferStorage(context), latestStorage);
ASSERT(packStorage);
ANGLE_TRY(packStorage->packPixels(context, readAttachment, params));
packStorage->setDataRevision(latestStorage ? latestStorage->getDataRevision() + 1 : 1);
onStorageUpdate(packStorage);
return gl::NoError();
}
......@@ -850,7 +848,7 @@ gl::Error Buffer11::updateBufferStorage(const gl::Context *context,
ANGLE_TRY_RESULT(stagingBuffer->copyFromStorage(context, latestBuffer, 0,
latestBuffer->getSize(), 0),
copyResult);
stagingBuffer->setDataRevision(latestBuffer->getDataRevision());
onCopyStorage(stagingBuffer, latestBuffer);
latestBuffer = stagingBuffer;
}
......@@ -864,7 +862,7 @@ gl::Error Buffer11::updateBufferStorage(const gl::Context *context,
{
updateSerial();
}
storage->setDataRevision(latestBuffer->getDataRevision());
onCopyStorage(storage, latestBuffer);
}
return gl::NoError();
......@@ -873,26 +871,13 @@ gl::Error Buffer11::updateBufferStorage(const gl::Context *context,
gl::ErrorOrResult<Buffer11::BufferStorage *> Buffer11::getLatestBufferStorage(
const gl::Context *context) const
{
// Even though we iterate over all the direct buffers, it is expected that only
// 1 or 2 will be present.
BufferStorage *latestStorage = nullptr;
DataRevision latestRevision = 0;
for (auto &storage : mBufferStorages)
{
if (storage && (!latestStorage || storage->getDataRevision() > latestRevision))
{
latestStorage = storage;
latestRevision = storage->getDataRevision();
}
}
// resize buffer
if (latestStorage && latestStorage->getSize() < mSize)
if (mLatestBufferStorage && mLatestBufferStorage->getSize() < mSize)
{
ANGLE_TRY(latestStorage->resize(context, mSize, true));
ANGLE_TRY(mLatestBufferStorage->resize(context, mSize, true));
}
return latestStorage;
return mLatestBufferStorage;
}
gl::ErrorOrResult<Buffer11::NativeStorage *> Buffer11::getStagingStorage(const gl::Context *context)
......@@ -942,6 +927,22 @@ OnBufferDataDirtyChannel *Buffer11::getDirectBroadcastChannel()
return &mDirectBroadcastChannel;
}
void Buffer11::onCopyStorage(BufferStorage *dest, BufferStorage *source)
{
ASSERT(source);
dest->setDataRevision(source->getDataRevision());
if (!mLatestBufferStorage || dest->getUsage() < mLatestBufferStorage->getUsage())
{
mLatestBufferStorage = dest;
}
}
void Buffer11::onStorageUpdate(BufferStorage *updatedStorage)
{
updatedStorage->setDataRevision(updatedStorage->getDataRevision() + 1);
mLatestBufferStorage = updatedStorage;
}
// Buffer11::BufferStorage implementation
Buffer11::BufferStorage::BufferStorage(Renderer11 *renderer, BufferUsage usage)
......
......@@ -152,12 +152,21 @@ class Buffer11 : public BufferD3D
// For some cases of uniform buffer storage, we can't deallocate system memory storage.
bool canDeallocateSystemMemory() const;
// Updates data revisions and latest storage.
void onCopyStorage(BufferStorage *dest, BufferStorage *source);
void onStorageUpdate(BufferStorage *updatedStorage);
Renderer11 *mRenderer;
size_t mSize;
BufferStorage *mMappedStorage;
// Buffer storages are sorted by usage. It's important that the latest buffer storage picks
// the lowest usage in the case where two storages are tied on data revision - this ensures
// we never do anything dangerous like map a uniform buffer over a staging or system memory
// copy.
std::array<BufferStorage *, BUFFER_USAGE_COUNT> mBufferStorages;
BufferStorage *mLatestBufferStorage;
// These two arrays are used to track when to free unused storage.
std::array<unsigned int, BUFFER_USAGE_COUNT> mDeallocThresholds;
......
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