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 @@
<ClInclude Include="..\..\src\libGLESv2\renderer\d3d\IndexBuffer.h"/>
<ClInclude Include="..\..\src\libGLESv2\renderer\d3d\HLSLCompiler.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\TextureStorage.h"/>
<ClInclude Include="..\..\src\libGLESv2\renderer\d3d\IndexDataManager.h"/>
......@@ -337,6 +338,7 @@
<ClCompile Include="..\..\src\libGLESv2\renderer\d3d\VertexBuffer.cpp"/>
<ClCompile Include="..\..\src\libGLESv2\renderer\d3d\TextureD3D.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\TextureStorage.cpp"/>
<ClCompile Include="..\..\src\libGLESv2\renderer\d3d\IndexDataManager.cpp"/>
......
......@@ -351,6 +351,9 @@
<ClCompile Include="..\..\src\libGLESv2\renderer\d3d\BufferD3D.cpp">
<Filter>src\libGLESv2\renderer\d3d</Filter>
</ClCompile>
<ClInclude Include="..\..\src\libGLESv2\renderer\d3d\MemoryBuffer.h">
<Filter>src\libGLESv2\renderer\d3d</Filter>
</ClInclude>
<ClCompile Include="..\..\src\libGLESv2\renderer\d3d\IndexBuffer.cpp">
<Filter>src\libGLESv2\renderer\d3d</Filter>
</ClCompile>
......@@ -369,6 +372,9 @@
<ClInclude Include="..\..\src\libGLESv2\renderer\d3d\TextureStorage.h">
<Filter>src\libGLESv2\renderer\d3d</Filter>
</ClInclude>
<ClCompile Include="..\..\src\libGLESv2\renderer\d3d\MemoryBuffer.cpp">
<Filter>src\libGLESv2\renderer\d3d</Filter>
</ClCompile>
<ClCompile Include="..\..\src\libGLESv2\renderer\d3d\ImageD3D.cpp">
<Filter>src\libGLESv2\renderer\d3d</Filter>
</ClCompile>
......
......@@ -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',
......
//
// 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
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);
}
}
......
......@@ -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;
......
......@@ -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);
......
......@@ -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;
};
......
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