Commit 5063f55a by Geoff Lang

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/209612Reviewed-by: 's avatarNico Weber <thakis@chromium.org> Tested-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 142ec426
...@@ -169,6 +169,7 @@ ...@@ -169,6 +169,7 @@
<ClInclude Include="..\..\src\libGLESv2\renderer\d3d\IndexBuffer.h"/> <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\IndexBuffer.h"/>
<ClInclude Include="..\..\src\libGLESv2\renderer\d3d\HLSLCompiler.h"/> <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\HLSLCompiler.h"/>
<ClInclude Include="..\..\src\libGLESv2\renderer\d3d\ImageD3D.h"/> <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\ImageD3D.h"/>
<ClInclude Include="..\..\src\libGLESv2\renderer\d3d\MemoryBuffer.h"/>
<ClInclude Include="..\..\src\libGLESv2\renderer\d3d\TextureD3D.h"/> <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\TextureD3D.h"/>
<ClInclude Include="..\..\src\libGLESv2\renderer\d3d\TextureStorage.h"/> <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\TextureStorage.h"/>
<ClInclude Include="..\..\src\libGLESv2\renderer\d3d\IndexDataManager.h"/> <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\IndexDataManager.h"/>
...@@ -337,6 +338,7 @@ ...@@ -337,6 +338,7 @@
<ClCompile Include="..\..\src\libGLESv2\renderer\d3d\VertexBuffer.cpp"/> <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\VertexBuffer.cpp"/>
<ClCompile Include="..\..\src\libGLESv2\renderer\d3d\TextureD3D.cpp"/> <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\TextureD3D.cpp"/>
<ClCompile Include="..\..\src\libGLESv2\renderer\d3d\VertexDataManager.cpp"/> <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\VertexDataManager.cpp"/>
<ClCompile Include="..\..\src\libGLESv2\renderer\d3d\MemoryBuffer.cpp"/>
<ClCompile Include="..\..\src\libGLESv2\renderer\d3d\ImageD3D.cpp"/> <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\ImageD3D.cpp"/>
<ClCompile Include="..\..\src\libGLESv2\renderer\d3d\TextureStorage.cpp"/> <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\TextureStorage.cpp"/>
<ClCompile Include="..\..\src\libGLESv2\renderer\d3d\IndexDataManager.cpp"/> <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\IndexDataManager.cpp"/>
......
...@@ -351,6 +351,9 @@ ...@@ -351,6 +351,9 @@
<ClCompile Include="..\..\src\libGLESv2\renderer\d3d\BufferD3D.cpp"> <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\BufferD3D.cpp">
<Filter>src\libGLESv2\renderer\d3d</Filter> <Filter>src\libGLESv2\renderer\d3d</Filter>
</ClCompile> </ClCompile>
<ClInclude Include="..\..\src\libGLESv2\renderer\d3d\MemoryBuffer.h">
<Filter>src\libGLESv2\renderer\d3d</Filter>
</ClInclude>
<ClCompile Include="..\..\src\libGLESv2\renderer\d3d\IndexBuffer.cpp"> <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\IndexBuffer.cpp">
<Filter>src\libGLESv2\renderer\d3d</Filter> <Filter>src\libGLESv2\renderer\d3d</Filter>
</ClCompile> </ClCompile>
...@@ -369,6 +372,9 @@ ...@@ -369,6 +372,9 @@
<ClInclude Include="..\..\src\libGLESv2\renderer\d3d\TextureStorage.h"> <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\TextureStorage.h">
<Filter>src\libGLESv2\renderer\d3d</Filter> <Filter>src\libGLESv2\renderer\d3d</Filter>
</ClInclude> </ClInclude>
<ClCompile Include="..\..\src\libGLESv2\renderer\d3d\MemoryBuffer.cpp">
<Filter>src\libGLESv2\renderer\d3d</Filter>
</ClCompile>
<ClCompile Include="..\..\src\libGLESv2\renderer\d3d\ImageD3D.cpp"> <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\ImageD3D.cpp">
<Filter>src\libGLESv2\renderer\d3d</Filter> <Filter>src\libGLESv2\renderer\d3d</Filter>
</ClCompile> </ClCompile>
......
...@@ -147,6 +147,8 @@ ...@@ -147,6 +147,8 @@
'libGLESv2/renderer/d3d/IndexBuffer.h', 'libGLESv2/renderer/d3d/IndexBuffer.h',
'libGLESv2/renderer/d3d/IndexDataManager.cpp', 'libGLESv2/renderer/d3d/IndexDataManager.cpp',
'libGLESv2/renderer/d3d/IndexDataManager.h', 'libGLESv2/renderer/d3d/IndexDataManager.h',
'libGLESv2/renderer/d3d/MemoryBuffer.cpp',
'libGLESv2/renderer/d3d/MemoryBuffer.h',
'libGLESv2/renderer/d3d/TextureD3D.cpp', 'libGLESv2/renderer/d3d/TextureD3D.cpp',
'libGLESv2/renderer/d3d/TextureD3D.h', 'libGLESv2/renderer/d3d/TextureD3D.h',
'libGLESv2/renderer/d3d/TextureStorage.cpp', 'libGLESv2/renderer/d3d/TextureStorage.cpp',
......
//
// 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;
}
}
//
// 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
...@@ -148,7 +148,7 @@ class Buffer11::PackStorage11 : public Buffer11::BufferStorage11 ...@@ -148,7 +148,7 @@ class Buffer11::PackStorage11 : public Buffer11::BufferStorage11
ID3D11Texture2D *mStagingTexture; ID3D11Texture2D *mStagingTexture;
DXGI_FORMAT mTextureFormat; DXGI_FORMAT mTextureFormat;
gl::Extents mTextureSize; gl::Extents mTextureSize;
std::vector<unsigned char> mMemoryBuffer; MemoryBuffer mMemoryBuffer;
PackPixelsParams *mQueuedPackCommand; PackPixelsParams *mQueuedPackCommand;
PackPixelsParams mPackParams; PackPixelsParams mPackParams;
bool mDataModified; bool mDataModified;
...@@ -215,7 +215,10 @@ void *Buffer11::getData() ...@@ -215,7 +215,10 @@ void *Buffer11::getData()
{ {
if (stagingBuffer->getSize() > mResolvedData.size()) 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(); ID3D11DeviceContext *context = mRenderer->getDeviceContext();
...@@ -789,7 +792,10 @@ bool Buffer11::PackStorage11::resize(size_t size, bool preserveData) ...@@ -789,7 +792,10 @@ bool Buffer11::PackStorage11::resize(size_t size, bool preserveData)
{ {
if (size != mBufferSize) if (size != mBufferSize)
{ {
mMemoryBuffer.resize(size, 0); if (!mMemoryBuffer.resize(size))
{
return false;
}
mBufferSize = size; mBufferSize = size;
} }
...@@ -807,7 +813,7 @@ void *Buffer11::PackStorage11::map(size_t offset, size_t length, GLbitfield acce ...@@ -807,7 +813,7 @@ void *Buffer11::PackStorage11::map(size_t offset, size_t length, GLbitfield acce
flushQueuedPackCommand(); flushQueuedPackCommand();
mDataModified = (mDataModified || (access & GL_MAP_WRITE_BIT) != 0); mDataModified = (mDataModified || (access & GL_MAP_WRITE_BIT) != 0);
return &mMemoryBuffer[0] + offset; return mMemoryBuffer.data() + offset;
} }
void Buffer11::PackStorage11::unmap() void Buffer11::PackStorage11::unmap()
...@@ -880,11 +886,11 @@ void Buffer11::PackStorage11::packPixels(ID3D11Texture2D *srcTexure, UINT srcSub ...@@ -880,11 +886,11 @@ void Buffer11::PackStorage11::packPixels(ID3D11Texture2D *srcTexure, UINT srcSub
void Buffer11::PackStorage11::flushQueuedPackCommand() void Buffer11::PackStorage11::flushQueuedPackCommand()
{ {
ASSERT(!mMemoryBuffer.empty()); ASSERT(mMemoryBuffer.size() > 0);
if (mQueuedPackCommand) if (mQueuedPackCommand)
{ {
mRenderer->packPixels(mStagingTexture, *mQueuedPackCommand, &mMemoryBuffer[0]); mRenderer->packPixels(mStagingTexture, *mQueuedPackCommand, mMemoryBuffer.data());
SafeDelete(mQueuedPackCommand); SafeDelete(mQueuedPackCommand);
} }
} }
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#define LIBGLESV2_RENDERER_BUFFER11_H_ #define LIBGLESV2_RENDERER_BUFFER11_H_
#include "libGLESv2/renderer/d3d/BufferD3D.h" #include "libGLESv2/renderer/d3d/BufferD3D.h"
#include "libGLESv2/renderer/d3d/MemoryBuffer.h"
#include "libGLESv2/angletypes.h" #include "libGLESv2/angletypes.h"
namespace rx namespace rx
...@@ -88,7 +89,7 @@ class Buffer11 : public BufferD3D ...@@ -88,7 +89,7 @@ class Buffer11 : public BufferD3D
typedef std::pair<ID3D11Buffer *, ID3D11ShaderResourceView *> BufferSRVPair; typedef std::pair<ID3D11Buffer *, ID3D11ShaderResourceView *> BufferSRVPair;
std::map<DXGI_FORMAT, BufferSRVPair> mBufferResourceViews; std::map<DXGI_FORMAT, BufferSRVPair> mBufferResourceViews;
std::vector<unsigned char> mResolvedData; MemoryBuffer mResolvedData;
DataRevision mResolvedDataRevision; DataRevision mResolvedDataRevision;
unsigned int mReadUsageCount; unsigned int mReadUsageCount;
......
...@@ -42,7 +42,10 @@ void Buffer9::setData(const void* data, size_t size, GLenum usage) ...@@ -42,7 +42,10 @@ void Buffer9::setData(const void* data, size_t size, GLenum usage)
{ {
if (size > mMemory.size()) if (size > mMemory.size())
{ {
mMemory.resize(size); if (!mMemory.resize(size))
{
return gl::error(GL_OUT_OF_MEMORY);
}
} }
mSize = size; mSize = size;
...@@ -70,7 +73,10 @@ void Buffer9::setSubData(const void* data, size_t size, size_t offset) ...@@ -70,7 +73,10 @@ void Buffer9::setSubData(const void* data, size_t size, size_t offset)
{ {
if (offset + size > mMemory.size()) 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); mSize = std::max(mSize, offset + size);
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#define LIBGLESV2_RENDERER_BUFFER9_H_ #define LIBGLESV2_RENDERER_BUFFER9_H_
#include "libGLESv2/renderer/d3d/BufferD3D.h" #include "libGLESv2/renderer/d3d/BufferD3D.h"
#include "libGLESv2/renderer/d3d/MemoryBuffer.h"
#include "libGLESv2/angletypes.h" #include "libGLESv2/angletypes.h"
namespace rx namespace rx
...@@ -43,7 +44,7 @@ class Buffer9 : public BufferD3D ...@@ -43,7 +44,7 @@ class Buffer9 : public BufferD3D
DISALLOW_COPY_AND_ASSIGN(Buffer9); DISALLOW_COPY_AND_ASSIGN(Buffer9);
rx::Renderer9 *mRenderer; rx::Renderer9 *mRenderer;
std::vector<char> mMemory; MemoryBuffer mMemory;
size_t mSize; size_t mSize;
}; };
......
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