diff options
author | Geoff Lang <geofflang@chromium.org> | 2014-07-23 16:27:31 -0400 |
---|---|---|
committer | Geoff Lang <geofflang@chromium.org> | 2014-07-24 17:57:48 +0000 |
commit | 5063f55a823348ef6ac774a10e12f410c98af7c8 (patch) | |
tree | c9f07dbc0dd7d1f172e02027c746571864089e39 /src | |
parent | 142ec4265cec061f5a695e949fa136b2cda636d8 (diff) | |
download | angle-5063f55a823348ef6ac774a10e12f410c98af7c8.tar.gz |
Add a MemoryBuffer type to safely allocate large user data buffers.
MemoryBuffer has a similar interface to std::vector but returns a bool on
resize to do error checking.
BUG=angle:700
Change-Id: Ib201eeb91b07f5b7f970e153f5d1e110f9b2fa55
Reviewed-on: https://chromium-review.googlesource.com/209612
Reviewed-by: Nico Weber <thakis@chromium.org>
Tested-by: Geoff Lang <geofflang@chromium.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/libGLESv2.gypi | 2 | ||||
-rw-r--r-- | src/libGLESv2/renderer/d3d/MemoryBuffer.cpp | 72 | ||||
-rw-r--r-- | src/libGLESv2/renderer/d3d/MemoryBuffer.h | 35 | ||||
-rw-r--r-- | src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp | 18 | ||||
-rw-r--r-- | src/libGLESv2/renderer/d3d/d3d11/Buffer11.h | 3 | ||||
-rw-r--r-- | src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp | 10 | ||||
-rw-r--r-- | src/libGLESv2/renderer/d3d/d3d9/Buffer9.h | 3 |
7 files changed, 133 insertions, 10 deletions
diff --git a/src/libGLESv2.gypi b/src/libGLESv2.gypi index 2256e7b3..f58967be 100644 --- a/src/libGLESv2.gypi +++ b/src/libGLESv2.gypi @@ -147,6 +147,8 @@ 'libGLESv2/renderer/d3d/IndexBuffer.h', 'libGLESv2/renderer/d3d/IndexDataManager.cpp', 'libGLESv2/renderer/d3d/IndexDataManager.h', + 'libGLESv2/renderer/d3d/MemoryBuffer.cpp', + 'libGLESv2/renderer/d3d/MemoryBuffer.h', 'libGLESv2/renderer/d3d/TextureD3D.cpp', 'libGLESv2/renderer/d3d/TextureD3D.h', 'libGLESv2/renderer/d3d/TextureStorage.cpp', diff --git a/src/libGLESv2/renderer/d3d/MemoryBuffer.cpp b/src/libGLESv2/renderer/d3d/MemoryBuffer.cpp new file mode 100644 index 00000000..301bbe8d --- /dev/null +++ b/src/libGLESv2/renderer/d3d/MemoryBuffer.cpp @@ -0,0 +1,72 @@ +// +// Copyright (c) 2014 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. +// + +#include "libGLESv2/renderer/d3d/MemoryBuffer.h" + +#include <algorithm> +#include <cstdlib> + +namespace rx +{ + +MemoryBuffer::MemoryBuffer() + : mSize(0), + mData(NULL) +{ +} + +MemoryBuffer::~MemoryBuffer() +{ + free(mData); + mData = NULL; +} + +bool MemoryBuffer::resize(size_t size) +{ + if (size == 0) + { + free(mData); + mData = NULL; + mSize = 0; + } + else + { + uint8_t *newMemory = reinterpret_cast<uint8_t*>(malloc(sizeof(uint8_t) * size)); + if (newMemory == NULL) + { + return false; + } + + if (mData) + { + // Copy the intersection of the old data and the new data + std::copy(mData, mData + std::min(mSize, size), newMemory); + free(mData); + } + + mData = newMemory; + mSize = size; + } + + return true; +} + +size_t MemoryBuffer::size() const +{ + return mSize; +} + +const uint8_t *MemoryBuffer::data() const +{ + return mData; +} + +uint8_t *MemoryBuffer::data() +{ + return mData; +} + +} diff --git a/src/libGLESv2/renderer/d3d/MemoryBuffer.h b/src/libGLESv2/renderer/d3d/MemoryBuffer.h new file mode 100644 index 00000000..2484c074 --- /dev/null +++ b/src/libGLESv2/renderer/d3d/MemoryBuffer.h @@ -0,0 +1,35 @@ +// +// Copyright (c) 2014 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. +// + +#ifndef LIBGLESV2_RENDERER_D3D_MEMORYBUFFER_H_ +#define LIBGLESV2_RENDERER_D3D_MEMORYBUFFER_H_ + +#include <cstddef> +#include <cstdint> + +namespace rx +{ + +class MemoryBuffer +{ + public: + MemoryBuffer(); + ~MemoryBuffer(); + + bool resize(size_t size); + size_t size() const; + + const uint8_t *data() const; + uint8_t *data(); + + private: + size_t mSize; + uint8_t *mData; +}; + +} + +#endif // LIBGLESV2_RENDERER_D3D_MEMORYBUFFER_H diff --git a/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp b/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp index facd7098..b677fb5f 100644 --- a/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp +++ b/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp @@ -148,7 +148,7 @@ class Buffer11::PackStorage11 : public Buffer11::BufferStorage11 ID3D11Texture2D *mStagingTexture; DXGI_FORMAT mTextureFormat; gl::Extents mTextureSize; - std::vector<unsigned char> mMemoryBuffer; + MemoryBuffer mMemoryBuffer; PackPixelsParams *mQueuedPackCommand; PackPixelsParams mPackParams; bool mDataModified; @@ -215,7 +215,10 @@ void *Buffer11::getData() { if (stagingBuffer->getSize() > mResolvedData.size()) { - mResolvedData.resize(stagingBuffer->getSize()); + if (!mResolvedData.resize(stagingBuffer->getSize())) + { + return gl::error(GL_OUT_OF_MEMORY, (void*)NULL); + } } ID3D11DeviceContext *context = mRenderer->getDeviceContext(); @@ -789,7 +792,10 @@ bool Buffer11::PackStorage11::resize(size_t size, bool preserveData) { if (size != mBufferSize) { - mMemoryBuffer.resize(size, 0); + if (!mMemoryBuffer.resize(size)) + { + return false; + } mBufferSize = size; } @@ -807,7 +813,7 @@ void *Buffer11::PackStorage11::map(size_t offset, size_t length, GLbitfield acce flushQueuedPackCommand(); mDataModified = (mDataModified || (access & GL_MAP_WRITE_BIT) != 0); - return &mMemoryBuffer[0] + offset; + return mMemoryBuffer.data() + offset; } void Buffer11::PackStorage11::unmap() @@ -880,11 +886,11 @@ void Buffer11::PackStorage11::packPixels(ID3D11Texture2D *srcTexure, UINT srcSub void Buffer11::PackStorage11::flushQueuedPackCommand() { - ASSERT(!mMemoryBuffer.empty()); + ASSERT(mMemoryBuffer.size() > 0); if (mQueuedPackCommand) { - mRenderer->packPixels(mStagingTexture, *mQueuedPackCommand, &mMemoryBuffer[0]); + mRenderer->packPixels(mStagingTexture, *mQueuedPackCommand, mMemoryBuffer.data()); SafeDelete(mQueuedPackCommand); } } diff --git a/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h b/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h index 43f95c34..e56be247 100644 --- a/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h +++ b/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h @@ -10,6 +10,7 @@ #define LIBGLESV2_RENDERER_BUFFER11_H_ #include "libGLESv2/renderer/d3d/BufferD3D.h" +#include "libGLESv2/renderer/d3d/MemoryBuffer.h" #include "libGLESv2/angletypes.h" namespace rx @@ -88,7 +89,7 @@ class Buffer11 : public BufferD3D typedef std::pair<ID3D11Buffer *, ID3D11ShaderResourceView *> BufferSRVPair; std::map<DXGI_FORMAT, BufferSRVPair> mBufferResourceViews; - std::vector<unsigned char> mResolvedData; + MemoryBuffer mResolvedData; DataRevision mResolvedDataRevision; unsigned int mReadUsageCount; diff --git a/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp b/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp index c86fe136..347bde0c 100644 --- a/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp +++ b/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp @@ -42,7 +42,10 @@ void Buffer9::setData(const void* data, size_t size, GLenum usage) { if (size > mMemory.size()) { - mMemory.resize(size); + if (!mMemory.resize(size)) + { + return gl::error(GL_OUT_OF_MEMORY); + } } mSize = size; @@ -70,7 +73,10 @@ void Buffer9::setSubData(const void* data, size_t size, size_t offset) { if (offset + size > mMemory.size()) { - mMemory.resize(offset + size); + if (!mMemory.resize(offset + size)) + { + return gl::error(GL_OUT_OF_MEMORY); + } } mSize = std::max(mSize, offset + size); diff --git a/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h b/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h index 0f80d074..ec25ec30 100644 --- a/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h +++ b/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h @@ -10,6 +10,7 @@ #define LIBGLESV2_RENDERER_BUFFER9_H_ #include "libGLESv2/renderer/d3d/BufferD3D.h" +#include "libGLESv2/renderer/d3d/MemoryBuffer.h" #include "libGLESv2/angletypes.h" namespace rx @@ -43,7 +44,7 @@ class Buffer9 : public BufferD3D DISALLOW_COPY_AND_ASSIGN(Buffer9); rx::Renderer9 *mRenderer; - std::vector<char> mMemory; + MemoryBuffer mMemory; size_t mSize; }; |