diff --git a/indra/llappearance/lltexlayer.cpp b/indra/llappearance/lltexlayer.cpp
index 3430a255368e7f10c4e583e5418ca578d491787b..e1a3a838418bea33a9a143534625dd1478e3df0d 100644
--- a/indra/llappearance/lltexlayer.cpp
+++ b/indra/llappearance/lltexlayer.cpp
@@ -1509,7 +1509,14 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
                 }
                 else
                 { // platforms with working drivers...
-				    glReadPixels(x, y, width, height, GL_ALPHA, GL_UNSIGNED_BYTE, alpha_data);                
+                    // We just want GL_ALPHA, but that isn't supported in OGL core profile 4.
+                    static const size_t TEMP_BYTES_PER_PIXEL = 4;
+                    U8* temp_data = (U8*)ll_aligned_malloc_32(mem_size * TEMP_BYTES_PER_PIXEL);
+                    glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, temp_data);
+                    for (size_t pixel = 0; pixel < pixels; pixel++) {
+                        alpha_data[pixel] = temp_data[(pixel * TEMP_BYTES_PER_PIXEL) + 3];
+                    }
+                    ll_aligned_free_32(temp_data);
                 }
 			}
             else
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 7cc5d33c4986bcd70a94906b03f5607f2aa90ebe..55713eea803dde29d31c4bc830baf0e4a6d71c9f 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -227,7 +227,6 @@ void LLGLSLShader::stopProfile(U32 count, U32 mode)
 
 void LLGLSLShader::placeProfileQuery()
 {
-#if 1 || !LL_DARWIN
     if (mTimerQuery == 0)
     {
         glGenQueries(1, &mSamplesQuery);
@@ -269,12 +268,10 @@ void LLGLSLShader::placeProfileQuery()
 
     glBeginQuery(GL_SAMPLES_PASSED, mSamplesQuery);
     glBeginQuery(GL_TIME_ELAPSED, mTimerQuery);
-#endif
 }
 
 void LLGLSLShader::readProfileQuery(U32 count, U32 mode)
 {
-#if !LL_DARWIN
     glEndQuery(GL_TIME_ELAPSED);
     glEndQuery(GL_SAMPLES_PASSED);
     
@@ -304,7 +301,6 @@ void LLGLSLShader::readProfileQuery(U32 count, U32 mode)
 
     sTotalDrawCalls++;
     mDrawCalls++;
-#endif
 }
 
 
@@ -676,7 +672,6 @@ void LLGLSLShader::mapUniform(GLint index, const vector<LLStaticHashedString> *
 
 
     glGetActiveUniform(mProgramObject, index, 1024, &length, &size, &type, (GLchar *)name);
-#if !LL_DARWIN
     if (size > 0)
     {
         switch(type)
@@ -718,7 +713,6 @@ void LLGLSLShader::mapUniform(GLint index, const vector<LLStaticHashedString> *
         }
         mTotalUniformSize += size;
     }
-#endif
 
     S32 location = glGetUniformLocation(mProgramObject, name);
     if (location != -1)
diff --git a/indra/llrender/llrender2dutils.cpp b/indra/llrender/llrender2dutils.cpp
index 5cb1dc6b25db6633dc8e6ddc9d52b50033a7dcf3..3d32d3ca3170074f4be61f25d7c02c9b7e78463a 100644
--- a/indra/llrender/llrender2dutils.cpp
+++ b/indra/llrender/llrender2dutils.cpp
@@ -1516,7 +1516,15 @@ void LLRender2D::loadIdentity()
 void LLRender2D::setLineWidth(F32 width)
 {
 	gGL.flush();
-	glLineWidth(width * lerp(LLRender::sUIGLScaleFactor.mV[VX], LLRender::sUIGLScaleFactor.mV[VY], 0.5f));
+    // If outside the allowed range, glLineWidth fails with "invalid value".
+    // On Darwin, the range is [1, 1].
+    static GLfloat range[2]{0.0};
+    if (range[1] == 0)
+    {
+        glGetFloatv(GL_SMOOTH_LINE_WIDTH_RANGE, range);
+    }
+    width *= lerp(LLRender::sUIGLScaleFactor.mV[VX], LLRender::sUIGLScaleFactor.mV[VY], 0.5f);
+    glLineWidth(llclamp(width, range[0], range[1]));
 }
 
 LLPointer<LLUIImage> LLRender2D::getUIImageByID(const LLUUID& image_id, S32 priority)
diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp
index 2179b441e504ed889f62bdb2207e0219fda6e75a..b0da054d760a775f0472db463706640765302539 100644
--- a/indra/llrender/llrendertarget.cpp
+++ b/indra/llrender/llrendertarget.cpp
@@ -301,13 +301,11 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
 	mTex.push_back(tex);
 	mInternalFormat.push_back(color_fmt);
 
-#if !LL_DARWIN
 	if (gDebugGL)
 	{ //bind and unbind to validate target
 		bindTarget();
 		flush();
 	}
-#endif
     
     
 	return true;
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index d05f916d95aa0dc0f634c1319f4223b27dc847ae..981175d845db887ee5e654bf4f4ad20bb5a3f38e 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -1327,7 +1327,6 @@ void LLVertexBuffer::setupVertexArray()
 
 			if (attrib_integer[i])
 			{
-#if !LL_DARWIN
 				//glVertexattribIPointer requires GLSL 1.30 or later
 				if (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 30)
 				{
@@ -1336,9 +1335,8 @@ void LLVertexBuffer::setupVertexArray()
 					// Cast via intptr_t to make it painfully obvious to the
 					// compiler that we're doing this intentionally.
 					glVertexAttribIPointer(i, attrib_size[i], attrib_type[i], sTypeSize[i],
-										   reinterpret_cast<const GLvoid*>(intptr_t(mOffsets[i]))); 
+										   reinterpret_cast<const GLvoid*>(intptr_t(mOffsets[i])));
 				}
-#endif
 			}
 			else
 			{
@@ -2364,11 +2362,9 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
 	if (data_mask & MAP_TEXTURE_INDEX && 
 			(gGLManager.mGLSLVersionMajor >= 2 || gGLManager.mGLSLVersionMinor >= 30)) //indexed texture rendering requires GLSL 1.30 or later
 	{
-#if !LL_DARWIN
 		S32 loc = TYPE_TEXTURE_INDEX;
 		void *ptr = (void*) (base + mOffsets[TYPE_VERTEX] + 12);
 		glVertexAttribIPointer(loc, 1, GL_UNSIGNED_INT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr);
-#endif
 	}
 	if (data_mask & MAP_VERTEX)
 	{
@@ -2459,11 +2455,9 @@ void LLVertexBuffer::setupVertexBufferFast(U32 data_mask)
     }
     if (data_mask & MAP_TEXTURE_INDEX)
     {
-#if !LL_DARWIN
         S32 loc = TYPE_TEXTURE_INDEX;
         void* ptr = (void*)(base + mOffsets[TYPE_VERTEX] + 12);
         glVertexAttribIPointer(loc, 1, GL_UNSIGNED_INT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr);
-#endif
     }
     if (data_mask & MAP_VERTEX)
     {