1/*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES Utilities
3 * ------------------------------------------------
4 *
5 * Copyright 2014 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 *      http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief Buffer object wrapper.
22 *//*--------------------------------------------------------------------*/
23
24#include "gluObjectWrapper.hpp"
25#include "gluRenderContext.hpp"
26#include "gluStrUtil.hpp"
27#include "glwFunctions.hpp"
28#include "glwEnums.hpp"
29
30#include <sstream>
31
32namespace glu
33{
34
35ObjectWrapper::ObjectWrapper (const glw::Functions& gl, const ObjectTraits& traits)
36	: m_gl		(gl)
37	, m_traits	(traits)
38	, m_object	(0)
39{
40	(gl.*traits.genFunc)(1, &m_object);
41
42	if (m_object == 0)
43	{
44		const deUint32		err			= gl.getError();
45		const char*			objectName	= traits.name;
46		std::ostringstream	msg;
47
48		msg << "Failed to create " << objectName << " object, got " << getErrorStr((int)err);
49
50		if (err == GL_OUT_OF_MEMORY)
51			throw OutOfMemoryError(msg.str());
52		else
53			throw Error((int)err, msg.str());
54	}
55}
56
57ObjectWrapper::~ObjectWrapper (void)
58{
59	(m_gl.*m_traits.deleteFunc)(1, &m_object);
60}
61
62static const ObjectTraits s_objectTraits[OBJECTTYPE_LAST] =
63{
64	{ "texture",			&glw::Functions::genTextures, 			&glw::Functions::deleteTextures				},
65	{ "buffer",				&glw::Functions::genBuffers, 			&glw::Functions::deleteBuffers				},
66	{ "renderbuffer",		&glw::Functions::genRenderbuffers, 		&glw::Functions::deleteRenderbuffers		},
67	{ "framebuffer",		&glw::Functions::genFramebuffers, 		&glw::Functions::deleteFramebuffers			},
68	{ "transform feedback",	&glw::Functions::genTransformFeedbacks,	&glw::Functions::deleteTransformFeedbacks	},
69	{ "vertex array",		&glw::Functions::genVertexArrays, 		&glw::Functions::deleteVertexArrays			},
70	{ "query",				&glw::Functions::genQueries, 			&glw::Functions::deleteQueries				},
71};
72
73const ObjectTraits& objectTraits (ObjectType type)
74{
75	return de::getSizedArrayElement<OBJECTTYPE_LAST>(s_objectTraits, type);
76}
77
78ObjectVector::ObjectVector (const glw::Functions& gl, const ObjectTraits& traits, size_t numObjects)
79	: m_gl		(gl)
80	, m_traits	(traits)
81{
82	if (numObjects > 0)
83		resize(numObjects);
84}
85
86ObjectVector::~ObjectVector (void)
87{
88	clear();
89}
90
91void ObjectVector::resize (size_t newSize)
92{
93	const size_t oldSize = m_objects.size();
94
95	if (newSize == 0)
96	{
97		clear(); // Avoid size_t (unsigned) overflow issues in delete path.
98	}
99	if (oldSize < newSize)
100	{
101		m_objects.resize(newSize, 0);
102		(m_gl.*m_traits.genFunc)(glw::GLsizei(newSize - oldSize), &m_objects[oldSize]);
103	}
104	else if (oldSize > newSize)
105	{
106		(m_gl.*m_traits.deleteFunc)(glw::GLsizei(oldSize - newSize), &m_objects[newSize]);
107		m_objects.resize(newSize);
108	}
109}
110
111void ObjectVector::clear (void)
112{
113	(m_gl.*m_traits.deleteFunc)(glw::GLsizei(m_objects.size()), &m_objects.front());
114	m_objects.clear();
115}
116
117} // glu
118