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#include "deArrayUtil.hpp"
30
31#include <sstream>
32
33namespace glu
34{
35
36ObjectWrapper::ObjectWrapper (const glw::Functions& gl, const ObjectTraits& traits)
37	: m_gl		(gl)
38	, m_traits	(traits)
39	, m_object	(0)
40{
41	(gl.*traits.genFunc)(1, &m_object);
42
43	if (m_object == 0)
44	{
45		const deUint32		err			= gl.getError();
46		const char*			objectName	= traits.name;
47		std::ostringstream	msg;
48
49		msg << "Failed to create " << objectName << " object, got " << getErrorStr((int)err);
50
51		if (err == GL_OUT_OF_MEMORY)
52			throw OutOfMemoryError(msg.str());
53		else
54			throw Error((int)err, msg.str());
55	}
56}
57
58ObjectWrapper::ObjectWrapper (const glw::Functions& gl, const ObjectTraits& traits, deUint32 object)
59	: m_gl		(gl)
60	, m_traits	(traits)
61	, m_object	(object)
62{
63	DE_ASSERT(object != 0);
64}
65
66ObjectWrapper::~ObjectWrapper (void)
67{
68	(m_gl.*m_traits.deleteFunc)(1, &m_object);
69}
70
71static const ObjectTraits s_objectTraits[OBJECTTYPE_LAST] =
72{
73	{ "texture",			&glw::Functions::genTextures,			&glw::Functions::deleteTextures				},
74	{ "buffer",				&glw::Functions::genBuffers,			&glw::Functions::deleteBuffers				},
75	{ "renderbuffer",		&glw::Functions::genRenderbuffers,		&glw::Functions::deleteRenderbuffers		},
76	{ "framebuffer",		&glw::Functions::genFramebuffers,		&glw::Functions::deleteFramebuffers			},
77	{ "transform feedback",	&glw::Functions::genTransformFeedbacks,	&glw::Functions::deleteTransformFeedbacks	},
78	{ "vertex array",		&glw::Functions::genVertexArrays,		&glw::Functions::deleteVertexArrays			},
79	{ "query",				&glw::Functions::genQueries,			&glw::Functions::deleteQueries				},
80	{ "sampler",			&glw::Functions::genSamplers,			&glw::Functions::deleteSamplers				},
81};
82
83const ObjectTraits& objectTraits (ObjectType type)
84{
85	return de::getSizedArrayElement<OBJECTTYPE_LAST>(s_objectTraits, type);
86}
87
88ObjectVector::ObjectVector (const glw::Functions& gl, const ObjectTraits& traits, size_t numObjects)
89	: m_gl		(gl)
90	, m_traits	(traits)
91{
92	if (numObjects > 0)
93		resize(numObjects);
94}
95
96ObjectVector::~ObjectVector (void)
97{
98	clear();
99}
100
101void ObjectVector::resize (size_t newSize)
102{
103	const size_t oldSize = m_objects.size();
104
105	if (newSize == 0)
106	{
107		clear(); // Avoid size_t (unsigned) overflow issues in delete path.
108	}
109	if (oldSize < newSize)
110	{
111		m_objects.resize(newSize, 0);
112		(m_gl.*m_traits.genFunc)(glw::GLsizei(newSize - oldSize), &m_objects[oldSize]);
113	}
114	else if (oldSize > newSize)
115	{
116		(m_gl.*m_traits.deleteFunc)(glw::GLsizei(oldSize - newSize), &m_objects[newSize]);
117		m_objects.resize(newSize);
118	}
119}
120
121void ObjectVector::clear (void)
122{
123	(m_gl.*m_traits.deleteFunc)(glw::GLsizei(m_objects.size()), &m_objects.front());
124	m_objects.clear();
125}
126
127} // glu
128