summaryrefslogtreecommitdiff
path: root/slideshow
diff options
context:
space:
mode:
authorEmmanuel Gil Peyrot <emmanuel.peyrot@collabora.com>2015-11-19 17:18:55 +0000
committerTor Lillqvist <tml@collabora.com>2015-11-19 19:21:48 +0200
commite18da092ef9a81202c9ec941bcb9876f257eed5b (patch)
tree1ed88646902ff93afcc7c8cd475e183e9e220226 /slideshow
parent04e2caeba5e346fb5d415d633b1956ef24c41037 (diff)
slideshow: Batch primitive display as much as possible
We now set the state and upload all vertices data at once, before each batch, in order to minimize GL calls during drawing. The next step will be to move to shaders, in order to use per-primitive uniforms instead of changing the global modelview matrix and issuing another draw call. Change-Id: I8c7cf29047047b9cad575cc6264485ae77d6ba10
Diffstat (limited to 'slideshow')
-rw-r--r--slideshow/source/engine/OGLTrans/generic/OGLTrans_TransitionImpl.cxx120
-rw-r--r--slideshow/source/engine/OGLTrans/generic/OGLTrans_TransitionImpl.hxx39
2 files changed, 100 insertions, 59 deletions
diff --git a/slideshow/source/engine/OGLTrans/generic/OGLTrans_TransitionImpl.cxx b/slideshow/source/engine/OGLTrans/generic/OGLTrans_TransitionImpl.cxx
index 11e6c4e92093..a7fa892decd1 100644
--- a/slideshow/source/engine/OGLTrans/generic/OGLTrans_TransitionImpl.cxx
+++ b/slideshow/source/engine/OGLTrans/generic/OGLTrans_TransitionImpl.cxx
@@ -192,6 +192,58 @@ void OGLTransitionImpl::applyOverallOperations( double nTime, double SlideWidthS
rOverallOperations[i]->interpolate(nTime,SlideWidthScale,SlideHeightScale);
}
+static void display_primitives(const Primitives_t& primitives, double nTime, double WidthScale, double HeightScale)
+{
+ CHECK_GL_ERROR();
+ GLuint buffer;
+ glGenBuffers(1, &buffer);
+ CHECK_GL_ERROR();
+ glBindBuffer(GL_ARRAY_BUFFER, buffer);
+
+ int size = 0;
+ for (const Primitive& primitive: primitives)
+ size += primitive.getVerticesSize();
+
+ CHECK_GL_ERROR();
+ glBufferData(GL_ARRAY_BUFFER, size, nullptr, GL_STREAM_DRAW);
+ CHECK_GL_ERROR();
+ Vertex *buf = reinterpret_cast<Vertex*>(glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY));
+
+ std::vector<int> first_elements;
+ int last_pos = 0;
+ for (const Primitive& primitive: primitives) {
+ first_elements.push_back(last_pos);
+ int num = primitive.writeVertices(buf);
+ buf += num;
+ last_pos += num;
+ }
+ auto first = first_elements.begin();
+
+ CHECK_GL_ERROR();
+ glUnmapBuffer(GL_ARRAY_BUFFER);
+
+ // State initialization
+ // TODO: move that elsewhere.
+ CHECK_GL_ERROR();
+ glEnableClientState( GL_VERTEX_ARRAY );
+ CHECK_GL_ERROR();
+ glVertexPointer( 3, GL_FLOAT, sizeof(Vertex), reinterpret_cast<void*>(offsetof(Vertex, position)) );
+ CHECK_GL_ERROR();
+ glEnableClientState( GL_NORMAL_ARRAY );
+ CHECK_GL_ERROR();
+ glNormalPointer( GL_FLOAT , sizeof(Vertex) , reinterpret_cast<void*>(offsetof(Vertex, normal)) );
+ CHECK_GL_ERROR();
+ glEnableClientState( GL_TEXTURE_COORD_ARRAY );
+ CHECK_GL_ERROR();
+ glTexCoordPointer( 2, GL_FLOAT, sizeof(Vertex), reinterpret_cast<void*>(offsetof(Vertex, texcoord)) );
+
+ for (const Primitive& primitive: primitives)
+ primitive.display(nTime, WidthScale, HeightScale, *first++);
+
+ CHECK_GL_ERROR();
+ glDeleteBuffers(1, &buffer);
+}
+
void
OGLTransitionImpl::displaySlide(
const double nTime,
@@ -216,8 +268,7 @@ OGLTransitionImpl::displaySlide(
glTranslated( 0, 2 - surfaceLevel, 0 );
glCullFace(GL_FRONT);
- for(size_t i(0); i < primitives.size(); ++i)
- primitives[i].display(nTime, SlideWidthScale, SlideHeightScale);
+ display_primitives(primitives, nTime, SlideWidthScale, SlideHeightScale);
glCullFace(GL_BACK);
slideShadow( nTime, primitives[0], SlideWidthScale, SlideHeightScale );
@@ -225,8 +276,7 @@ OGLTransitionImpl::displaySlide(
glPopMatrix();
}
- for(size_t i(0); i < primitives.size(); ++i)
- primitives[i].display(nTime, SlideWidthScale, SlideHeightScale);
+ display_primitives(primitives, nTime, SlideWidthScale, SlideHeightScale);
CHECK_GL_ERROR();
}
@@ -240,7 +290,7 @@ void OGLTransitionImpl::displayScene( double nTime, double SlideWidth, double Sl
CHECK_GL_ERROR();
}
-void Primitive::display(double nTime, double WidthScale, double HeightScale) const
+void Primitive::display(double nTime, double WidthScale, double HeightScale, int first) const
{
CHECK_GL_ERROR();
glPushMatrix();
@@ -249,19 +299,8 @@ void Primitive::display(double nTime, double WidthScale, double HeightScale) con
applyOperations( nTime, WidthScale, HeightScale );
CHECK_GL_ERROR();
- glEnableClientState( GL_VERTEX_ARRAY );
- CHECK_GL_ERROR();
- glNormalPointer( GL_FLOAT , 0 , &Normals[0] );
- CHECK_GL_ERROR();
- glEnableClientState( GL_NORMAL_ARRAY );
- CHECK_GL_ERROR();
- glEnableClientState( GL_TEXTURE_COORD_ARRAY );
- CHECK_GL_ERROR();
- glTexCoordPointer( 2, GL_FLOAT, 0, &TexCoords[0] );
- CHECK_GL_ERROR();
- glVertexPointer( 3, GL_FLOAT, 0, &Vertices[0] );
- CHECK_GL_ERROR();
- glDrawArrays( GL_TRIANGLES, 0, Vertices.size() );
+ glDrawArrays( GL_TRIANGLES, first, Vertices.size() );
+
CHECK_GL_ERROR();
glPopMatrix();
CHECK_GL_ERROR();
@@ -278,22 +317,19 @@ void Primitive::applyOperations(double nTime, double WidthScale, double HeightSc
void SceneObject::display(double nTime, double /* SlideWidth */, double /* SlideHeight */, double DispWidth, double DispHeight ) const
{
+ // fixme: allow various model spaces, now we make it so that
+ // it is regular -1,-1 to 1,1, where the whole display fits in
CHECK_GL_ERROR();
- for(size_t i(0); i < maPrimitives.size(); ++i) {
- // fixme: allow various model spaces, now we make it so that
- // it is regular -1,-1 to 1,1, where the whole display fits in
- CHECK_GL_ERROR();
- glPushMatrix();
- CHECK_GL_ERROR();
- if (DispHeight > DispWidth)
- glScaled(DispHeight/DispWidth, 1, 1);
- else
- glScaled(1, DispWidth/DispHeight, 1);
- maPrimitives[i].display(nTime, 1, 1);
- CHECK_GL_ERROR();
- glPopMatrix();
- CHECK_GL_ERROR();
- }
+ glPushMatrix();
+ CHECK_GL_ERROR();
+ if (DispHeight > DispWidth)
+ glScaled(DispHeight/DispWidth, 1, 1);
+ else
+ glScaled(1, DispWidth/DispHeight, 1);
+ CHECK_GL_ERROR();
+ display_primitives(maPrimitives, nTime, 1, 1);
+ CHECK_GL_ERROR();
+ glPopMatrix();
CHECK_GL_ERROR();
}
@@ -1063,8 +1099,6 @@ Primitive& Primitive::operator=(const Primitive& rvalue)
Primitive::Primitive(const Primitive& rvalue)
: Operations(rvalue.Operations)
, Vertices(rvalue.Vertices)
- , Normals(rvalue.Normals)
- , TexCoords(rvalue.TexCoords)
{
}
@@ -1074,8 +1108,6 @@ void Primitive::swap(Primitive& rOther)
swap(Operations, rOther.Operations);
swap(Vertices, rOther.Vertices);
- swap(Normals, rOther.Normals);
- swap(TexCoords, rOther.TexCoords);
}
void Primitive::pushTriangle(const glm::vec2& SlideLocation0,const glm::vec2& SlideLocation1,const glm::vec2& SlideLocation2)
@@ -1108,17 +1140,9 @@ void Primitive::pushTriangle(const glm::vec2& SlideLocation0,const glm::vec2& Sl
Verts.push_back(glm::vec3( 2*SlideLocation1.x - 1, -2*SlideLocation1.y + 1 , 0.0 ));
}
- Vertices.push_back(Verts[0]);
- Vertices.push_back(Verts[1]);
- Vertices.push_back(Verts[2]);
-
- TexCoords.push_back(Texs[0]);
- TexCoords.push_back(Texs[1]);
- TexCoords.push_back(Texs[2]);
-
- Normals.push_back(glm::vec3(0,0,1));//all normals always face the screen when untransformed.
- Normals.push_back(glm::vec3(0,0,1));//all normals always face the screen when untransformed.
- Normals.push_back(glm::vec3(0,0,1));//all normals always face the screen when untransformed.
+ Vertices.push_back({Verts[0], glm::vec3(0, 0, 1), Texs[0]}); //all normals always face the screen when untransformed.
+ Vertices.push_back({Verts[1], glm::vec3(0, 0, 1), Texs[1]}); //all normals always face the screen when untransformed.
+ Vertices.push_back({Verts[2], glm::vec3(0, 0, 1), Texs[2]}); //all normals always face the screen when untransformed.
}
namespace
diff --git a/slideshow/source/engine/OGLTrans/generic/OGLTrans_TransitionImpl.hxx b/slideshow/source/engine/OGLTrans/generic/OGLTrans_TransitionImpl.hxx
index 37df57e86e56..972cb83a61e5 100644
--- a/slideshow/source/engine/OGLTrans/generic/OGLTrans_TransitionImpl.hxx
+++ b/slideshow/source/engine/OGLTrans/generic/OGLTrans_TransitionImpl.hxx
@@ -277,6 +277,14 @@ private:
GLuint maTexture;
};
+struct Vertex
+{
+ glm::vec3 position;
+ glm::vec3 normal;
+ glm::vec2 texcoord;
+};
+static_assert(sizeof(Vertex) == (3 + 3 + 2) * 4, "Vertex struct has wrong size/alignment");
+
/** This class is a list of Triangles that will share Operations, and could possibly share
*/
class Primitive
@@ -290,7 +298,7 @@ public:
void swap(Primitive& rOther);
void applyOperations(double nTime, double SlideWidthScale, double SlideHeightScale) const;
- void display(double nTime, double SlideWidthScale, double SlideHeightScale) const;
+ void display(double nTime, double SlideWidthScale, double SlideHeightScale, int first) const;
/** PushBack a vertex,normal, and tex coord. Each SlideLocation is where on the slide is mapped to this location ( from (0,0) to (1,1) ). This will make sure the correct aspect ratio is used, and helps to make slides begin and end at the correct position. (0,0) is the top left of the slide, and (1,1) is the bottom right.
@@ -311,7 +319,24 @@ public:
@return
the list of vertices
*/
- const glm::vec3& getVertex(int n) const {return Vertices[n];}
+ const glm::vec3& getVertex(int n) const {return Vertices[n].position;}
+
+ /** accessor for the size of the vertices data
+
+ @return
+ the size in bytes of the Vertices data
+ */
+ int getVerticesSize() const {return Vertices.size() * sizeof(Vertex);}
+
+ /** copies all vertices to the C array passed
+
+ @return
+ the number of written vertices
+ */
+ int writeVertices(Vertex *location) const {
+ std::copy(Vertices.begin(), Vertices.end(), location);
+ return Vertices.size();
+ }
/** list of Operations to be performed on this primitive.These operations will be called in the order they were pushed back in. In OpenGL this effectively uses the operations in the opposite order they were pushed back.
@@ -324,15 +349,7 @@ public:
private:
/** list of vertices
*/
- std::vector<glm::vec3> Vertices;
-
- /** list of Normals
- */
- std::vector<glm::vec3> Normals;
-
- /** list of Texture Coordinates
- */
- std::vector<glm::vec2> TexCoords;
+ std::vector<Vertex> Vertices;
};
/** This class is to be derived to make any operation (transform) you may need in order to construct your transitions