blob: 4dca1c9cfdfdee90b4c96191ab4ef86b1fd2c4fa [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
Geoff Langeeba6e12014-02-03 13:12:30 -05002// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003// 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
Geoff Lang2b5420c2014-11-19 14:20:15 -050011#include "libANGLE/Buffer.h"
12#include "libANGLE/renderer/BufferImpl.h"
13#include "libANGLE/renderer/Renderer.h"
daniel@transgaming.com83921382011-01-08 05:46:00 +000014
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000015namespace gl
16{
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000017
Brandon Jonesd38f9262014-06-18 16:26:45 -070018Buffer::Buffer(rx::BufferImpl *impl, GLuint id)
Jamie Madill103a11f2014-02-24 15:27:21 -050019 : RefCountObject(id),
Brandon Jonesd38f9262014-06-18 16:26:45 -070020 mBuffer(impl),
Geoff Langec6bae72015-04-29 13:54:15 -040021 mUsage(GL_STATIC_DRAW),
Brandon Jonesd38f9262014-06-18 16:26:45 -070022 mSize(0),
Jamie Madill103a11f2014-02-24 15:27:21 -050023 mAccessFlags(0),
Geoff Langcc6f55d2015-03-20 13:01:02 -040024 mAccess(GL_WRITE_ONLY_OES),
Jamie Madill103a11f2014-02-24 15:27:21 -050025 mMapped(GL_FALSE),
26 mMapPointer(NULL),
27 mMapOffset(0),
Brandon Jonesd38f9262014-06-18 16:26:45 -070028 mMapLength(0)
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +000029{
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000030}
31
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +000032Buffer::~Buffer()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000033{
Jamie Madillef9d63e2014-08-04 10:48:02 -040034 SafeDelete(mBuffer);
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +000035}
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000036
Geoff Lang2a1c15a2014-07-25 11:43:00 -040037Error Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage)
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +000038{
Geoff Lang2a1c15a2014-07-25 11:43:00 -040039 gl::Error error = mBuffer->setData(data, size, usage);
40 if (error.isError())
41 {
42 return error;
43 }
44
Jamie Madillef9d63e2014-08-04 10:48:02 -040045 mIndexRangeCache.clear();
daniel@transgaming.comaa0ccbd2010-04-15 20:45:05 +000046 mUsage = usage;
Brandon Jonesd38f9262014-06-18 16:26:45 -070047 mSize = size;
Geoff Lang2a1c15a2014-07-25 11:43:00 -040048
49 return error;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000050}
51
Geoff Lang2a1c15a2014-07-25 11:43:00 -040052Error Buffer::bufferSubData(const void *data, GLsizeiptr size, GLintptr offset)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000053{
Geoff Lang2a1c15a2014-07-25 11:43:00 -040054 gl::Error error = mBuffer->setSubData(data, size, offset);
55 if (error.isError())
56 {
57 return error;
58 }
59
Minmin Gong794e0002015-04-07 18:31:54 -070060 mIndexRangeCache.invalidateRange(static_cast<unsigned int>(offset), static_cast<unsigned int>(size));
Geoff Lang2a1c15a2014-07-25 11:43:00 -040061
62 return error;
daniel@transgaming.com83921382011-01-08 05:46:00 +000063}
64
Geoff Lang2a1c15a2014-07-25 11:43:00 -040065Error Buffer::copyBufferSubData(Buffer* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com614c07f2013-04-13 03:39:32 +000066{
Geoff Lang2a1c15a2014-07-25 11:43:00 -040067 gl::Error error = mBuffer->copySubData(source->getImplementation(), sourceOffset, destOffset, size);
68 if (error.isError())
69 {
70 return error;
71 }
72
Minmin Gong794e0002015-04-07 18:31:54 -070073 mIndexRangeCache.invalidateRange(static_cast<unsigned int>(destOffset), static_cast<unsigned int>(size));
Geoff Lang2a1c15a2014-07-25 11:43:00 -040074
75 return error;
shannon.woods%transgaming.com@gtempaccount.com614c07f2013-04-13 03:39:32 +000076}
77
Geoff Langcc6f55d2015-03-20 13:01:02 -040078Error Buffer::map(GLenum access)
79{
80 ASSERT(!mMapped);
81
82 Error error = mBuffer->map(access, &mMapPointer);
83 if (error.isError())
84 {
85 mMapPointer = NULL;
86 return error;
87 }
88
89 ASSERT(access == GL_WRITE_ONLY_OES);
90
91 mMapped = GL_TRUE;
92 mMapOffset = 0;
93 mMapLength = mSize;
94 mAccess = access;
95 mAccessFlags = GL_MAP_WRITE_BIT;
Geoff Lang520c4ae2015-05-05 13:12:36 -040096 mIndexRangeCache.clear();
Geoff Langcc6f55d2015-03-20 13:01:02 -040097
98 return error;
99}
100
Geoff Lang2a1c15a2014-07-25 11:43:00 -0400101Error Buffer::mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access)
Jamie Madill103a11f2014-02-24 15:27:21 -0500102{
103 ASSERT(!mMapped);
Brandon Jonesd38f9262014-06-18 16:26:45 -0700104 ASSERT(offset + length <= mSize);
Jamie Madill103a11f2014-02-24 15:27:21 -0500105
Geoff Langcc6f55d2015-03-20 13:01:02 -0400106 Error error = mBuffer->mapRange(offset, length, access, &mMapPointer);
Geoff Lang2a1c15a2014-07-25 11:43:00 -0400107 if (error.isError())
108 {
109 mMapPointer = NULL;
110 return error;
111 }
Jamie Madill103a11f2014-02-24 15:27:21 -0500112
113 mMapped = GL_TRUE;
Jamie Madill103a11f2014-02-24 15:27:21 -0500114 mMapOffset = static_cast<GLint64>(offset);
115 mMapLength = static_cast<GLint64>(length);
Geoff Langcc6f55d2015-03-20 13:01:02 -0400116 mAccess = GL_WRITE_ONLY_OES;
117 mAccessFlags = access;
118
119 // The OES_mapbuffer extension states that GL_WRITE_ONLY_OES is the only valid
120 // value for GL_BUFFER_ACCESS_OES because it was written against ES2. Since there is
121 // no update for ES3 and the GL_READ_ONLY and GL_READ_WRITE enums don't exist for ES,
122 // we cannot properly set GL_BUFFER_ACCESS_OES when glMapBufferRange is called.
Jamie Madill103a11f2014-02-24 15:27:21 -0500123
Jamie Madillef9d63e2014-08-04 10:48:02 -0400124 if ((access & GL_MAP_WRITE_BIT) > 0)
125 {
Minmin Gong794e0002015-04-07 18:31:54 -0700126 mIndexRangeCache.invalidateRange(static_cast<unsigned int>(offset), static_cast<unsigned int>(length));
Jamie Madillef9d63e2014-08-04 10:48:02 -0400127 }
128
Geoff Lang2a1c15a2014-07-25 11:43:00 -0400129 return error;
Jamie Madill103a11f2014-02-24 15:27:21 -0500130}
131
Geoff Langcc6f55d2015-03-20 13:01:02 -0400132Error Buffer::unmap(GLboolean *result)
Jamie Madill103a11f2014-02-24 15:27:21 -0500133{
134 ASSERT(mMapped);
135
Geoff Langcc6f55d2015-03-20 13:01:02 -0400136 Error error = mBuffer->unmap(result);
Geoff Lang2a1c15a2014-07-25 11:43:00 -0400137 if (error.isError())
138 {
Geoff Langcc6f55d2015-03-20 13:01:02 -0400139 *result = GL_FALSE;
Geoff Lang2a1c15a2014-07-25 11:43:00 -0400140 return error;
141 }
Jamie Madill103a11f2014-02-24 15:27:21 -0500142
143 mMapped = GL_FALSE;
144 mMapPointer = NULL;
145 mMapOffset = 0;
146 mMapLength = 0;
Geoff Langcc6f55d2015-03-20 13:01:02 -0400147 mAccess = GL_WRITE_ONLY_OES;
Jamie Madill103a11f2014-02-24 15:27:21 -0500148 mAccessFlags = 0;
Geoff Lang2a1c15a2014-07-25 11:43:00 -0400149
150 return error;
Jamie Madill103a11f2014-02-24 15:27:21 -0500151}
152
Geoff Lang520c4ae2015-05-05 13:12:36 -0400153void Buffer::onTransformFeedback()
154{
155 mIndexRangeCache.clear();
156}
157
158void Buffer::onPixelUnpack()
159{
160 mIndexRangeCache.clear();
161}
162
163Error Buffer::getIndexRange(GLenum type, size_t offset, size_t count, gl::RangeUI *outRange) const
164{
Cooper Partinc5cf9bc2015-08-06 10:46:48 -0700165 if (mIndexRangeCache.findRange(type, static_cast<unsigned int>(offset),
166 static_cast<GLsizei>(count), outRange))
Geoff Lang520c4ae2015-05-05 13:12:36 -0400167 {
168 return gl::Error(GL_NO_ERROR);
169 }
170
171 Error error = mBuffer->getIndexRange(type, offset, count, outRange);
172 if (error.isError())
173 {
174 return error;
175 }
176
Cooper Partinc5cf9bc2015-08-06 10:46:48 -0700177 mIndexRangeCache.addRange(type, static_cast<unsigned int>(offset), static_cast<GLsizei>(count),
178 *outRange);
Geoff Lang520c4ae2015-05-05 13:12:36 -0400179
180 return Error(GL_NO_ERROR);
181}
182
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000183}