From e4d0d62e71de69d1685d00da571e9055e18fdc0c Mon Sep 17 00:00:00 2001
From: Don Kjer <don@lindenlab.com>
Date: Sat, 9 Jul 2011 22:30:30 -0700
Subject: [PATCH] Added support for apple flush buffer range

---
 indra/llrender/llgl.cpp           |  2 +
 indra/llrender/llgl.h             |  1 +
 indra/llrender/llvertexbuffer.cpp | 89 ++++++++++++++++++++++---------
 indra/newview/llface.cpp          |  2 +-
 4 files changed, 69 insertions(+), 25 deletions(-)

diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index c224ab0e9bb..02c975a17a2 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -337,6 +337,7 @@ LLGLManager::LLGLManager() :
 
 	mHasVertexBufferObject(FALSE),
 	mHasMapBufferRange(FALSE),
+	mHasFlushBufferRange(FALSE),
 	mHasPBuffer(FALSE),
 	mHasShaderObjects(FALSE),
 	mHasVertexShader(FALSE),
@@ -775,6 +776,7 @@ void LLGLManager::initExtensions()
 	mHasOcclusionQuery2 = ExtensionExists("GL_ARB_occlusion_query2", gGLHExts.mSysExts);
 	mHasVertexBufferObject = ExtensionExists("GL_ARB_vertex_buffer_object", gGLHExts.mSysExts);
 	mHasMapBufferRange = ExtensionExists("GL_ARB_map_buffer_range", gGLHExts.mSysExts);
+	mHasFlushBufferRange = ExtensionExists("GL_APPLE_flush_buffer_range", gGLHExts.mSysExts);
 	mHasDepthClamp = ExtensionExists("GL_ARB_depth_clamp", gGLHExts.mSysExts) || ExtensionExists("GL_NV_depth_clamp", gGLHExts.mSysExts);
 	// mask out FBO support when packed_depth_stencil isn't there 'cause we need it for LLRenderTarget -Brad
 #ifdef GL_ARB_framebuffer_object
diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h
index d1bee001617..3e98c043215 100644
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -89,6 +89,7 @@ class LLGLManager
 	// ARB Extensions
 	BOOL mHasVertexBufferObject;
 	BOOL mHasMapBufferRange;
+	BOOL mHasFlushBufferRange;
 	BOOL mHasPBuffer;
 	BOOL mHasShaderObjects;
 	BOOL mHasVertexShader;
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 6c972647f83..db9c8f83f81 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -968,7 +968,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran
 	if (useVBOs())
 	{
 
-		if (sDisableVBOMapping || gGLManager.mHasMapBufferRange)
+		if (sDisableVBOMapping || gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange)
 		{
 			if (count == -1)
 			{
@@ -1019,29 +1019,44 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran
 			else
 			{
 				U8* src = NULL;
-#ifdef GL_ARB_map_buffer_range
 				if (gGLManager.mHasMapBufferRange)
 				{
 					if (map_range)
 					{
+#ifdef GL_ARB_map_buffer_range
 						S32 offset = mOffsets[type] + sTypeSize[type]*index;
 						S32 length = (sTypeSize[type]*count+0xF) & ~0xF;
 						src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER_ARB, offset, length, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_INVALIDATE_RANGE_BIT);
+#endif
 					}
 					else
 					{
+#ifdef GL_ARB_map_buffer_range
 						src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER_ARB, 0, mSize, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);
+#endif
+					}
+				}
+				else if (gGLManager.mHasFlushBufferRange)
+				{
+					if (map_range)
+					{
+						glBufferParameteriAPPLE(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE);
+						glBufferParameteriAPPLE(GL_ARRAY_BUFFER_ARB, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE);
+						src = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+					}
+					else
+					{
+						src = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
 					}
 				}
 				else
-#else
-				llassert_always(!gGLManager.mHasMapBufferRange);
-#endif
 				{
 					map_range = false;
 					src = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
 				}
 
+				llassert(src != NULL);
+
 				mMappedData = LL_NEXT_ALIGNED_ADDRESS<U8>(src);
 				mAlignedOffset = mMappedData - src;
 			
@@ -1090,7 +1105,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran
 		map_range = false;
 	}
 	
-	if (map_range && !sDisableVBOMapping)
+	if (map_range && gGLManager.mHasMapBufferRange && !sDisableVBOMapping)
 	{
 		return mMappedData;
 	}
@@ -1114,7 +1129,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
 
 	if (useVBOs())
 	{
-		if (sDisableVBOMapping || gGLManager.mHasMapBufferRange)
+		if (sDisableVBOMapping || gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange)
 		{
 			if (count == -1)
 			{
@@ -1163,29 +1178,45 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
 			else
 			{
 				U8* src = NULL;
-#ifdef GL_ARB_map_buffer_range
 				if (gGLManager.mHasMapBufferRange)
 				{
 					if (map_range)
 					{
+#ifdef GL_ARB_map_buffer_range
 						S32 offset = sizeof(U16)*index;
 						S32 length = sizeof(U16)*count;
 						src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_INVALIDATE_RANGE_BIT);
+#endif
 					}
 					else
 					{
+#ifdef GL_ARB_map_buffer_range
 						src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, sizeof(U16)*mNumIndices, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);
+#endif
+					}
+				}
+				else if (gGLManager.mHasFlushBufferRange)
+				{
+					if (map_range)
+					{
+						glBufferParameteriAPPLE(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE);
+						glBufferParameteriAPPLE(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE);
+						src = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+					}
+					else
+					{
+						src = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
 					}
 				}
 				else
-#else
-				llassert_always(!gGLManager.mHasMapBufferRange);
-#endif
 				{
 					map_range = false;
 					src = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
 				}
 
+				llassert(src != NULL);
+
+
 				mMappedIndexData = src; //LL_NEXT_ALIGNED_ADDRESS<U8>(src);
 				mAlignedIndexOffset = mMappedIndexData - src;
 				stop_glerror();
@@ -1218,7 +1249,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
 		map_range = false;
 	}
 
-	if (map_range && !sDisableVBOMapping)
+	if (map_range && gGLManager.mHasMapBufferRange && !sDisableVBOMapping)
 	{
 		return mMappedIndexData;
 	}
@@ -1267,8 +1298,7 @@ void LLVertexBuffer::unmapBuffer(S32 type)
 		}
 		else
 		{
-#ifdef GL_ARB_map_buffer_range
-			if (gGLManager.mHasMapBufferRange)
+			if (gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange)
 			{
 				if (!mMappedVertexRegions.empty())
 				{
@@ -1278,16 +1308,22 @@ void LLVertexBuffer::unmapBuffer(S32 type)
 						const MappedRegion& region = mMappedVertexRegions[i];
 						S32 offset = region.mIndex >= 0 ? mOffsets[region.mType]+sTypeSize[region.mType]*region.mIndex : 0;
 						S32 length = sTypeSize[region.mType]*region.mCount;
-						glFlushMappedBufferRange(GL_ARRAY_BUFFER_ARB, offset, length);
+						if (gGLManager.mHasMapBufferRange)
+						{
+#ifdef GL_ARB_map_buffer_range
+							glFlushMappedBufferRange(GL_ARRAY_BUFFER_ARB, offset, length);
+#endif
+						}
+						else if (gGLManager.mHasFlushBufferRange)
+						{
+							glFlushMappedBufferRangeAPPLE(GL_ARRAY_BUFFER_ARB, offset, length);
+						}
 						stop_glerror();
 					}
 
 					mMappedVertexRegions.clear();
 				}
 			}
-#else
-			llassert_always(!gGLManager.mHasMapBufferRange);
-#endif
 			stop_glerror();
 			glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
 			stop_glerror();
@@ -1325,8 +1361,7 @@ void LLVertexBuffer::unmapBuffer(S32 type)
 		}
 		else
 		{
-#ifdef GL_ARB_map_buffer_range
-			if (gGLManager.mHasMapBufferRange)
+			if (gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange)
 			{
 				if (!mMappedIndexRegions.empty())
 				{
@@ -1335,16 +1370,22 @@ void LLVertexBuffer::unmapBuffer(S32 type)
 						const MappedRegion& region = mMappedIndexRegions[i];
 						S32 offset = region.mIndex >= 0 ? sizeof(U16)*region.mIndex : 0;
 						S32 length = sizeof(U16)*region.mCount;
-						glFlushMappedBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length);
+						if (gGLManager.mHasMapBufferRange)
+						{
+#ifdef GL_ARB_map_buffer_range
+							glFlushMappedBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length);
+#endif
+						}
+						else if (gGLManager.mHasFlushBufferRange)
+						{
+							glFlushMappedBufferRangeAPPLE(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length);
+						}
 						stop_glerror();
 					}
 
 					mMappedIndexRegions.clear();
 				}
 			}
-#else
-			llassert_always(!gGLManager.mHasMapBufferRange);
-#endif
 			stop_glerror();
 			glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
 			stop_glerror();
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index d2b05d10882..59c6e904a13 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -1064,7 +1064,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
 	S32 num_vertices = (S32)vf.mNumVertices;
 	S32 num_indices = (S32) vf.mNumIndices;
 	
-	bool map_range = gGLManager.mHasMapBufferRange;
+	bool map_range = gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange;
 
 	if (mVertexBuffer.notNull())
 	{
-- 
GitLab