Remove "All rights reserved" line from license headers.
[profile/ivi/qtdeclarative.git] / src / quick / scenegraph / coreapi / qsggeometry.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the Qt scene graph research project.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qsggeometry.h"
43 #include "qsggeometry_p.h"
44
45 #include <qopenglcontext.h>
46 #include <qopenglfunctions.h>
47 #include <private/qopenglextensions_p.h>
48
49 QT_BEGIN_NAMESPACE
50
51
52 QSGGeometry::Attribute QSGGeometry::Attribute::create(int attributeIndex, int tupleSize, int primitiveType, bool isPrimitive)
53 {
54     Attribute a = { attributeIndex, tupleSize, primitiveType, isPrimitive, 0 };
55     return a;
56 }
57
58
59 /*!
60     Convenience function which returns attributes to be used for 2D solid
61     color drawing.
62  */
63
64 const QSGGeometry::AttributeSet &QSGGeometry::defaultAttributes_Point2D()
65 {
66     static Attribute data[] = {
67         QSGGeometry::Attribute::create(0, 2, GL_FLOAT, true)
68     };
69     static AttributeSet attrs = { 1, sizeof(float) * 2, data };
70     return attrs;
71 }
72
73 /*!
74     Convenience function which returns attributes to be used for textured 2D drawing.
75  */
76
77 const QSGGeometry::AttributeSet &QSGGeometry::defaultAttributes_TexturedPoint2D()
78 {
79     static Attribute data[] = {
80         QSGGeometry::Attribute::create(0, 2, GL_FLOAT, true),
81         QSGGeometry::Attribute::create(1, 2, GL_FLOAT)
82     };
83     static AttributeSet attrs = { 2, sizeof(float) * 4, data };
84     return attrs;
85 }
86
87 /*!
88     Convenience function which returns attributes to be used for per vertex colored 2D drawing.
89  */
90
91 const QSGGeometry::AttributeSet &QSGGeometry::defaultAttributes_ColoredPoint2D()
92 {
93     static Attribute data[] = {
94         QSGGeometry::Attribute::create(0, 2, GL_FLOAT, true),
95         QSGGeometry::Attribute::create(1, 4, GL_UNSIGNED_BYTE)
96     };
97     static AttributeSet attrs = { 2, 2 * sizeof(float) + 4 * sizeof(char), data };
98     return attrs;
99 }
100
101
102 /*!
103     \class QSGGeometry
104     \brief The QSGGeometry class provides low-level storage for graphics primitives
105     in the QML Scene Graph.
106
107     The QSGGeometry class provides a few convenience attributes and attribute accessors
108     by default. The defaultAttributes_Point2D() function returns attributes to be used
109     in normal solid color rectangles, while the defaultAttributes_TexturedPoint2D function
110     returns attributes to be used for the common pixmap usecase.
111  */
112
113
114 /*!
115     Constructs a geometry object based on \a attributes.
116
117     The object allocate space for \a vertexCount vertices based on the accumulated
118     size in \a attributes and for \a indexCount.
119
120     Geometry objects are constructed with GL_TRIANGLE_STRIP as default drawing mode.
121
122     The attribute structure is assumed to be POD and the geometry object
123     assumes this will not go away. There is no memory management involved.
124  */
125
126 QSGGeometry::QSGGeometry(const QSGGeometry::AttributeSet &attributes,
127                          int vertexCount,
128                          int indexCount,
129                          int indexType)
130     : m_drawing_mode(GL_TRIANGLE_STRIP)
131     , m_vertex_count(0)
132     , m_index_count(0)
133     , m_index_type(indexType)
134     , m_attributes(attributes)
135     , m_data(0)
136     , m_index_data_offset(-1)
137     , m_server_data(0)
138     , m_owns_data(false)
139     , m_index_usage_pattern(AlwaysUploadPattern)
140     , m_vertex_usage_pattern(AlwaysUploadPattern)
141     , m_line_width(1.0)
142 {
143     Q_ASSERT(m_attributes.count > 0);
144     Q_ASSERT(m_attributes.stride > 0);
145
146     Q_ASSERT_X(indexType != GL_UNSIGNED_INT
147                || static_cast<QOpenGLExtensions *>(QOpenGLContext::currentContext()->functions())
148                   ->hasOpenGLExtension(QOpenGLExtensions::ElementIndexUint),
149                "QSGGeometry::QSGGeometry",
150                "GL_UNSIGNED_INT is not supported, geometry will not render"
151                );
152
153     if (indexType != GL_UNSIGNED_BYTE
154         && indexType != GL_UNSIGNED_SHORT
155         && indexType != GL_UNSIGNED_INT) {
156         qFatal("QSGGeometry: Unsupported index type, %x.\n", indexType);
157     }
158
159
160     // Because allocate reads m_vertex_count, m_index_count and m_owns_data, these
161     // need to be set before calling allocate...
162     allocate(vertexCount, indexCount);
163 }
164
165 /*!
166     \fn int QSGGeometry::sizeOfVertex() const
167
168     Returns the size in bytes of one vertex.
169
170     This value comes from the attributes.
171  */
172
173 /*!
174     \fn int QSGGeometry::sizeOfIndex() const
175
176     Returns the byte size of the index type.
177
178     This value is either 1 when index type is GL_UNSIGNED_BYTE or 2 when
179     index type is GL_UNSIGNED_SHORT. For Desktop OpenGL, GL_UNSIGNED_INT
180     with the value 4 is also supported.
181  */
182
183 QSGGeometry::~QSGGeometry()
184 {
185     if (m_owns_data)
186         free(m_data);
187
188     if (m_server_data)
189         delete m_server_data;
190 }
191
192 /*!
193     \fn int QSGGeometry::vertexCount() const
194
195     Returns the number of vertices in this geometry object.
196  */
197
198 /*!
199     \fn int QSGGeometry::indexCount() const
200
201     Returns the number of indices in this geometry object.
202  */
203
204
205
206 /*!
207     \fn void *QSGGeometry::vertexData()
208
209     Returns a pointer to the raw vertex data of this geometry object.
210
211     \sa vertexDataAsPoint2D(), vertexDataAsTexturedPoint2D
212  */
213
214 /*!
215     \fn const void *QSGGeometry::vertexData() const
216
217     Returns a pointer to the raw vertex data of this geometry object.
218
219     \sa vertexDataAsPoint2D(), vertexDataAsTexturedPoint2D
220  */
221
222 /*!
223     Returns a pointer to the raw index data of this geometry object.
224
225     \sa indexDataAsUShort(), indexDataAsUInt()
226  */
227 void *QSGGeometry::indexData()
228 {
229     return m_index_data_offset < 0
230             ? 0
231             : ((char *) m_data + m_index_data_offset);
232 }
233
234 /*!
235     Returns a pointer to the raw index data of this geometry object.
236
237     \sa indexDataAsUShort(), indexDataAsUInt()
238  */
239 const void *QSGGeometry::indexData() const
240 {
241     return m_index_data_offset < 0
242             ? 0
243             : ((char *) m_data + m_index_data_offset);
244 }
245
246 /*!
247     Sets the drawing mode to be used for this geometry.
248
249     The default value is GL_TRIANGLE_STRIP.
250  */
251 void QSGGeometry::setDrawingMode(GLenum mode)
252 {
253     m_drawing_mode = mode;
254 }
255
256 /*!
257     Gets the current line width to be used for this geometry. This property only
258     applies where the drawingMode is GL_LINES or a related value.
259
260     The default value is 1.0
261
262     \sa setLineWidth(), drawingMode()
263 */
264 float QSGGeometry::lineWidth() const
265 {
266     return m_line_width;
267 }
268
269 /*!
270     Sets the line width to be used for this geometry. This property only applies
271     where the drawingMode is GL_LINES or a related value.
272
273     \sa lineWidth(), drawingMode()
274 */
275 void QSGGeometry::setLineWidth(float w)
276 {
277     m_line_width = w;
278 }
279
280 /*!
281     \fn int QSGGeometry::drawingMode() const
282
283     Returns the drawing mode of this geometry.
284
285     The default value is GL_TRIANGLE_STRIP.
286  */
287
288 /*!
289     \fn int QSGGeometry::indexType() const
290
291     Returns the primitive type used for indices in this
292     geometry object.
293  */
294
295
296 /*!
297     Resizes the vertex and index data of this geometry object to fit \a vertexCount
298     vertices and \a indexCount indices.
299
300     Vertex and index data will be invalidated after this call and the caller must
301  */
302 void QSGGeometry::allocate(int vertexCount, int indexCount)
303 {
304     if (vertexCount == m_vertex_count && indexCount == m_index_count)
305         return;
306
307     m_vertex_count = vertexCount;
308     m_index_count = indexCount;
309
310     bool canUsePrealloc = m_index_count <= 0;
311     int vertexByteSize = m_attributes.stride * m_vertex_count;
312
313     if (m_owns_data)
314         free(m_data);
315
316     if (canUsePrealloc && vertexByteSize <= (int) sizeof(m_prealloc)) {
317         m_data = (void *) &m_prealloc[0];
318         m_index_data_offset = -1;
319         m_owns_data = false;
320     } else {
321         Q_ASSERT(m_index_type == GL_UNSIGNED_INT || m_index_type == GL_UNSIGNED_SHORT);
322         int indexByteSize = indexCount * (m_index_type == GL_UNSIGNED_SHORT ? sizeof(quint16) : sizeof(quint32));
323         m_data = (void *) malloc(vertexByteSize + indexByteSize);
324         m_index_data_offset = vertexByteSize;
325         m_owns_data = true;
326     }
327
328     // If we have associated vbo data we could potentially crash later if
329     // the old buffers are used with the new vertex and index count, so we force
330     // an update in the renderer in that case. This is really the users responsibility
331     // but it is cheap for us to enforce this, so why not...
332     if (m_server_data) {
333         markIndexDataDirty();
334         markVertexDataDirty();
335     }
336
337 }
338
339 /*!
340     Updates the geometry \a g with the coordinates in \a rect.
341
342     The function assumes the geometry object contains a single triangle strip
343     of QSGGeometry::Point2D vertices
344  */
345 void QSGGeometry::updateRectGeometry(QSGGeometry *g, const QRectF &rect)
346 {
347     Point2D *v = g->vertexDataAsPoint2D();
348     v[0].x = rect.left();
349     v[0].y = rect.top();
350
351     v[1].x = rect.left();
352     v[1].y = rect.bottom();
353
354     v[2].x = rect.right();
355     v[2].y = rect.top();
356
357     v[3].x = rect.right();
358     v[3].y = rect.bottom();
359 }
360
361 /*!
362     Updates the geometry \a g with the coordinates in \a rect and texture
363     coordinates from \a textureRect.
364
365     \a textureRect should be in normalized coordinates.
366
367     \a g is assumed to be a triangle strip of four vertices of type
368     QSGGeometry::TexturedPoint2D.
369  */
370 void QSGGeometry::updateTexturedRectGeometry(QSGGeometry *g, const QRectF &rect, const QRectF &textureRect)
371 {
372     TexturedPoint2D *v = g->vertexDataAsTexturedPoint2D();
373     v[0].x = rect.left();
374     v[0].y = rect.top();
375     v[0].tx = textureRect.left();
376     v[0].ty = textureRect.top();
377
378     v[1].x = rect.left();
379     v[1].y = rect.bottom();
380     v[1].tx = textureRect.left();
381     v[1].ty = textureRect.bottom();
382
383     v[2].x = rect.right();
384     v[2].y = rect.top();
385     v[2].tx = textureRect.right();
386     v[2].ty = textureRect.top();
387
388     v[3].x = rect.right();
389     v[3].y = rect.bottom();
390     v[3].tx = textureRect.right();
391     v[3].ty = textureRect.bottom();
392 }
393
394
395
396 /*!
397     \enum QSGGeometry::DataPattern
398
399     The DataPattern enum is used to specify the use pattern for the vertex
400     and index data in a geometry object.
401
402     \value AlwaysUploadPattern The data is always uploaded. This means that
403     the user does not need to explicitly mark index and vertex data as
404     dirty after changing it. This is the default.
405
406     \value DynamicPattern The data is modified repeatedly and drawn many times.
407     This is a hint that may provide better performance. When set
408     the user must make sure to mark the data as dirty after changing it.
409
410     \value StaticPattern The data is modified once and drawn many times. This is
411     a hint that may provide better performance. When set the user must make sure
412     to mark the data as dirty after changing it.
413  */
414
415
416 /*!
417     \fn QSGGeometry::DataPattern QSGGeometry::indexDataPattern() const
418
419     Returns the usage pattern for indices in this geometry. The default
420     pattern is AlwaysUploadPattern.
421  */
422
423 /*!
424     Sets the usage pattern for indices to \a p.
425
426     The default is AlwaysUploadPattern. When set to anything other than
427     the default, the user must call markIndexDataDirty() after changing
428     the index data.
429  */
430
431 void QSGGeometry::setIndexDataPattern(DataPattern p)
432 {
433     m_index_usage_pattern = p;
434 }
435
436
437
438
439 /*!
440     \fn QSGGeometry::DataPattern QSGGeometry::vertexDataPattern() const
441
442     Returns the usage pattern for vertices in this geometry. The default
443     pattern is AlwaysUploadPattern.
444  */
445
446 /*!
447     Sets the usage pattern for vertices to \a p.
448
449     The default is AlwaysUploadPattern. When set to anything other than
450     the default, the user must call markVertexDataDirty() after changing
451     the vertex data.
452  */
453
454 void QSGGeometry::setVertexDataPattern(DataPattern p)
455 {
456     m_vertex_usage_pattern = p;
457 }
458
459
460
461
462 /*!
463     Mark that the vertices in this geometry has changed and must be uploaded
464     again.
465
466     This function only has an effect when the usage pattern for vertices is
467     StaticData and the renderer that renders this geometry uploads the geometry
468     into Vertex Buffer Objects (VBOs).
469  */
470 void QSGGeometry::markIndexDataDirty()
471 {
472     m_dirty_index_data = true;
473 }
474
475
476
477 /*!
478     Mark that the vertices in this geometry has changed and must be uploaded
479     again.
480
481     This function only has an effect when the usage pattern for vertices is
482     StaticData and the renderer that renders this geometry uploads the geometry
483     into Vertex Buffer Objects (VBOs).
484  */
485 void QSGGeometry::markVertexDataDirty()
486 {
487     m_dirty_vertex_data = true;
488 }
489
490
491 QT_END_NAMESPACE