In order for OpenGL to execute a geometry shader, it must perform what is known as "primitive assembly". When you render a series of triangles via GL_TRIANGLE_STRIP
, OpenGL will do internal stuff to convert every 3 adjacent vertices into an individual triangle, modifying the winding order appropriately.
Each index from an element array buffer will produce the same outputs from a vertex shader. So the GPU will often cache these outputs in a post-T&L cache. If it sees an index that is already in the cache, the VS is not run again; it just fetches data from the cache.
Adding to this is the fact that many GL 3.x-class GPUs (aka: DX10) had rather small post-GS buffers. The smaller the buffer, the fewer GS invocations you can have active simultaneously. So your hardware effectively bottlenecks on the GS. Because tessellation is a big feature of 4.x class hardware, most such hardware has buffers sufficient to make heavier GS use viable.