blob: 5baeb79f679ffd3680086c79d036b025b39ffbd9 [file] [log] [blame]
//
// Copyright 2002 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.
//
// VertexBuffer.h: Defines the abstract VertexBuffer class and VertexBufferInterface
// class with derivations, classes that perform graphics API agnostic vertex buffer operations.
#ifndef LIBANGLE_RENDERER_D3D_VERTEXBUFFER_H_
#define LIBANGLE_RENDERER_D3D_VERTEXBUFFER_H_
#include "common/PackedEnums.h"
#include "common/angleutils.h"
#include "libANGLE/Error.h"
#include "libANGLE/renderer/Format.h"
#include <GLES2/gl2.h>
#include <cstddef>
#include <cstdint>
#include <vector>
namespace gl
{
class Context;
struct VertexAttribute;
class VertexBinding;
struct VertexAttribCurrentValueData;
} // namespace gl
namespace rx
{
class BufferFactoryD3D;
// Use a ref-counting scheme with self-deletion on release. We do this so that we can more
// easily manage the static buffer cache, without deleting currently bound buffers.
class VertexBuffer : angle::NonCopyable
{
public:
VertexBuffer();
virtual angle::Result initialize(const gl::Context *context,
unsigned int size,
bool dynamicUsage) = 0;
// Warning: you should ensure binding really matches attrib.bindingIndex before using this
// function.
virtual angle::Result storeVertexAttributes(const gl::Context *context,
const gl::VertexAttribute &attrib,
const gl::VertexBinding &binding,
gl::VertexAttribType currentValueType,
GLint start,
size_t count,
GLsizei instances,
unsigned int offset,
const uint8_t *sourceData) = 0;
virtual unsigned int getBufferSize() const = 0;
virtual angle::Result setBufferSize(const gl::Context *context, unsigned int size) = 0;
virtual angle::Result discard(const gl::Context *context) = 0;
unsigned int getSerial() const;
// This may be overridden (e.g. by VertexBuffer11) if necessary.
virtual void hintUnmapResource() {}
// Reference counting.
void addRef();
void release();
protected:
void updateSerial();
virtual ~VertexBuffer();
private:
unsigned int mSerial;
static unsigned int mNextSerial;
unsigned int mRefCount;
};
class VertexBufferInterface : angle::NonCopyable
{
public:
VertexBufferInterface(BufferFactoryD3D *factory, bool dynamic);
virtual ~VertexBufferInterface();
unsigned int getBufferSize() const;
bool empty() const { return getBufferSize() == 0; }
unsigned int getSerial() const;
VertexBuffer *getVertexBuffer() const;
protected:
angle::Result discard(const gl::Context *context);
angle::Result setBufferSize(const gl::Context *context, unsigned int size);
angle::Result getSpaceRequired(const gl::Context *context,
const gl::VertexAttribute &attrib,
const gl::VertexBinding &binding,
size_t count,
GLsizei instances,
unsigned int *spaceInBytesOut) const;
BufferFactoryD3D *const mFactory;
VertexBuffer *mVertexBuffer;
bool mDynamic;
};
class StreamingVertexBufferInterface : public VertexBufferInterface
{
public:
StreamingVertexBufferInterface(BufferFactoryD3D *factory);
~StreamingVertexBufferInterface() override;
angle::Result initialize(const gl::Context *context, std::size_t initialSize);
void reset();
angle::Result storeDynamicAttribute(const gl::Context *context,
const gl::VertexAttribute &attrib,
const gl::VertexBinding &binding,
gl::VertexAttribType currentValueType,
GLint start,
size_t count,
GLsizei instances,
unsigned int *outStreamOffset,
const uint8_t *sourceData);
angle::Result reserveVertexSpace(const gl::Context *context,
const gl::VertexAttribute &attribute,
const gl::VertexBinding &binding,
size_t count,
GLsizei instances);
private:
angle::Result reserveSpace(const gl::Context *context, unsigned int size);
unsigned int mWritePosition;
unsigned int mReservedSpace;
};
class StaticVertexBufferInterface : public VertexBufferInterface
{
public:
explicit StaticVertexBufferInterface(BufferFactoryD3D *factory);
~StaticVertexBufferInterface() override;
// Warning: you should ensure binding really matches attrib.bindingIndex before using these
// functions.
angle::Result storeStaticAttribute(const gl::Context *context,
const gl::VertexAttribute &attrib,
const gl::VertexBinding &binding,
GLint start,
GLsizei count,
GLsizei instances,
const uint8_t *sourceData);
bool matchesAttribute(const gl::VertexAttribute &attribute,
const gl::VertexBinding &binding) const;
void setAttribute(const gl::VertexAttribute &attribute, const gl::VertexBinding &binding);
private:
class AttributeSignature final : angle::NonCopyable
{
public:
AttributeSignature();
bool matchesAttribute(const gl::VertexAttribute &attrib,
const gl::VertexBinding &binding) const;
void set(const gl::VertexAttribute &attrib, const gl::VertexBinding &binding);
private:
angle::FormatID formatID;
GLuint stride;
size_t offset;
};
AttributeSignature mSignature;
};
} // namespace rx
#endif // LIBANGLE_RENDERER_D3D_VERTEXBUFFER_H_