1//
2// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// Buffer.cpp: Implements the gl::Buffer class, representing storage of vertex and/or
8// index data. Implements GL buffer objects and related functionality.
9// [OpenGL ES 2.0.24] section 2.9 page 21.
10
11#include "libGLESv2/Buffer.h"
12#include "libGLESv2/renderer/BufferImpl.h"
13#include "libGLESv2/renderer/Renderer.h"
14
15namespace gl
16{
17
18Buffer::Buffer(rx::BufferImpl *impl, GLuint id)
19    : RefCountObject(id),
20      mBuffer(impl),
21      mUsage(GL_DYNAMIC_DRAW),
22      mSize(0),
23      mAccessFlags(0),
24      mMapped(GL_FALSE),
25      mMapPointer(NULL),
26      mMapOffset(0),
27      mMapLength(0)
28{
29}
30
31Buffer::~Buffer()
32{
33    SafeDelete(mBuffer);
34}
35
36Error Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage)
37{
38    gl::Error error = mBuffer->setData(data, size, usage);
39    if (error.isError())
40    {
41        return error;
42    }
43
44    mIndexRangeCache.clear();
45    mUsage = usage;
46    mSize = size;
47
48    return error;
49}
50
51Error Buffer::bufferSubData(const void *data, GLsizeiptr size, GLintptr offset)
52{
53    gl::Error error = mBuffer->setSubData(data, size, offset);
54    if (error.isError())
55    {
56        return error;
57    }
58
59    mIndexRangeCache.invalidateRange(offset, size);
60
61    return error;
62}
63
64Error Buffer::copyBufferSubData(Buffer* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size)
65{
66    gl::Error error = mBuffer->copySubData(source->getImplementation(), sourceOffset, destOffset, size);
67    if (error.isError())
68    {
69        return error;
70    }
71
72    mIndexRangeCache.invalidateRange(destOffset, size);
73
74    return error;
75}
76
77Error Buffer::mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access)
78{
79    ASSERT(!mMapped);
80    ASSERT(offset + length <= mSize);
81
82    Error error = mBuffer->map(offset, length, access, &mMapPointer);
83    if (error.isError())
84    {
85        mMapPointer = NULL;
86        return error;
87    }
88
89    mMapped = GL_TRUE;
90    mMapOffset = static_cast<GLint64>(offset);
91    mMapLength = static_cast<GLint64>(length);
92    mAccessFlags = static_cast<GLint>(access);
93
94    if ((access & GL_MAP_WRITE_BIT) > 0)
95    {
96        mIndexRangeCache.invalidateRange(offset, length);
97    }
98
99    return error;
100}
101
102Error Buffer::unmap()
103{
104    ASSERT(mMapped);
105
106    Error error = mBuffer->unmap();
107    if (error.isError())
108    {
109        return error;
110    }
111
112    mMapped = GL_FALSE;
113    mMapPointer = NULL;
114    mMapOffset = 0;
115    mMapLength = 0;
116    mAccessFlags = 0;
117
118    return error;
119}
120
121void Buffer::markTransformFeedbackUsage()
122{
123    // TODO: Only used by the DX11 backend. Refactor to a more appropriate place.
124    mBuffer->markTransformFeedbackUsage();
125    mIndexRangeCache.clear();
126}
127
128}
129