Expose surfaceless context extension strings

It seems like SwiftShader already supports surfaceless contexts properly in
eglMakeCurrent, so we might as well expose the extension strings.

Change-Id: I3c1b85296c46536df9a8bd754856d825307181d0
Reviewed-on: https://swiftshader-review.googlesource.com/17948
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/OpenGL/libGLESv2/Context.cpp b/src/OpenGL/libGLESv2/Context.cpp
index 39e8c96..6233e8f 100644
--- a/src/OpenGL/libGLESv2/Context.cpp
+++ b/src/OpenGL/libGLESv2/Context.cpp
@@ -749,16 +749,32 @@
 
 void Context::setFramebufferReadBuffer(GLuint buf)
 {
-	getReadFramebuffer()->setReadBuffer(buf);
+	Framebuffer *framebuffer = getReadFramebuffer();
+
+	if(framebuffer)
+	{
+		framebuffer->setReadBuffer(buf);
+	}
+	else
+	{
+		return error(GL_INVALID_OPERATION);
+	}
 }
 
 void Context::setFramebufferDrawBuffers(GLsizei n, const GLenum *bufs)
 {
 	Framebuffer *drawFramebuffer = getDrawFramebuffer();
 
-	for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++)
+	if(drawFramebuffer)
 	{
-		drawFramebuffer->setDrawBuffer(i, (i < n) ? bufs[i] : GL_NONE);
+		for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++)
+		{
+			drawFramebuffer->setDrawBuffer(i, (i < n) ? bufs[i] : GL_NONE);
+		}
+	}
+	else
+	{
+		return error(GL_INVALID_OPERATION);
 	}
 }
 
@@ -1964,7 +1980,7 @@
 			Framebuffer *framebuffer = getDrawFramebuffer();
 			int width, height, samples;
 
-			if(framebuffer->completeness(width, height, samples) == GL_FRAMEBUFFER_COMPLETE)
+			if(framebuffer && (framebuffer->completeness(width, height, samples) == GL_FRAMEBUFFER_COMPLETE))
 			{
 				switch(pname)
 				{
@@ -1992,13 +2008,27 @@
 	case GL_IMPLEMENTATION_COLOR_READ_TYPE:
 		{
 			Framebuffer *framebuffer = getReadFramebuffer();
-			*params = framebuffer->getImplementationColorReadType();
+			if(framebuffer)
+			{
+				*params = framebuffer->getImplementationColorReadType();
+			}
+			else
+			{
+				return error(GL_INVALID_OPERATION, true);
+			}
 		}
 		return true;
 	case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
 		{
 			Framebuffer *framebuffer = getReadFramebuffer();
-			*params = framebuffer->getImplementationColorReadFormat();
+			if(framebuffer)
+			{
+				*params = framebuffer->getImplementationColorReadFormat();
+			}
+			else
+			{
+				return error(GL_INVALID_OPERATION, true);
+			}
 		}
 		return true;
 	case GL_MAX_VIEWPORT_DIMS:
@@ -2036,7 +2066,7 @@
 	case GL_ALPHA_BITS:
 		{
 			Framebuffer *framebuffer = getDrawFramebuffer();
-			Renderbuffer *colorbuffer = framebuffer->getColorbuffer(0);
+			Renderbuffer *colorbuffer = framebuffer ? framebuffer->getColorbuffer(0) : nullptr;
 
 			if(colorbuffer)
 			{
@@ -2057,7 +2087,7 @@
 	case GL_DEPTH_BITS:
 		{
 			Framebuffer *framebuffer = getDrawFramebuffer();
-			Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
+			Renderbuffer *depthbuffer = framebuffer ? framebuffer->getDepthbuffer() : nullptr;
 
 			if(depthbuffer)
 			{
@@ -2072,7 +2102,7 @@
 	case GL_STENCIL_BITS:
 		{
 			Framebuffer *framebuffer = getDrawFramebuffer();
-			Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
+			Renderbuffer *stencilbuffer = framebuffer ? framebuffer->getStencilbuffer() : nullptr;
 
 			if(stencilbuffer)
 			{
@@ -2147,7 +2177,8 @@
 	case GL_DRAW_BUFFER15:
 		if((pname - GL_DRAW_BUFFER0) < MAX_DRAW_BUFFERS)
 		{
-			*params = getDrawFramebuffer()->getDrawBuffer(pname - GL_DRAW_BUFFER0);
+			Framebuffer* framebuffer = getDrawFramebuffer();
+			*params = framebuffer ? framebuffer->getDrawBuffer(pname - GL_DRAW_BUFFER0) : GL_NONE;
 		}
 		else
 		{
@@ -2301,7 +2332,10 @@
 			// should be a 0 sized array, so don't write to params
 			return true;
 		case GL_READ_BUFFER:
-			*params = getReadFramebuffer()->getReadBuffer();
+			{
+				Framebuffer* framebuffer = getReadFramebuffer();
+				*params = framebuffer ? framebuffer->getReadBuffer() : GL_NONE;
+			}
 			return true;
 		case GL_SAMPLER_BINDING:
 			*params = mState.sampler[mState.activeSampler].name();
@@ -2721,7 +2755,7 @@
 	Framebuffer *framebuffer = getDrawFramebuffer();
 	int width, height, samples;
 
-	if(!framebuffer || framebuffer->completeness(width, height, samples) != GL_FRAMEBUFFER_COMPLETE)
+	if(!framebuffer || (framebuffer->completeness(width, height, samples) != GL_FRAMEBUFFER_COMPLETE))
 	{
 		return error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
 	}
@@ -3285,7 +3319,7 @@
 	Framebuffer *framebuffer = getReadFramebuffer();
 	int framebufferWidth, framebufferHeight, framebufferSamples;
 
-	if(framebuffer->completeness(framebufferWidth, framebufferHeight, framebufferSamples) != GL_FRAMEBUFFER_COMPLETE)
+	if(!framebuffer || (framebuffer->completeness(framebufferWidth, framebufferHeight, framebufferSamples) != GL_FRAMEBUFFER_COMPLETE))
 	{
 		return error(GL_INVALID_FRAMEBUFFER_OPERATION);
 	}
@@ -3354,7 +3388,7 @@
 
 	Framebuffer *framebuffer = getDrawFramebuffer();
 
-	if(!framebuffer || framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
+	if(!framebuffer || (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE))
 	{
 		return error(GL_INVALID_FRAMEBUFFER_OPERATION);
 	}
@@ -3399,6 +3433,10 @@
 	if(rgbaMask && !mState.rasterizerDiscardEnabled)
 	{
 		Framebuffer *framebuffer = getDrawFramebuffer();
+		if(!framebuffer)
+		{
+			return error(GL_INVALID_FRAMEBUFFER_OPERATION);
+		}
 		egl::Image *colorbuffer = framebuffer->getRenderTarget(drawbuffer);
 
 		if(colorbuffer)
@@ -3437,6 +3475,10 @@
 	if(mState.depthMask && !mState.rasterizerDiscardEnabled)
 	{
 		Framebuffer *framebuffer = getDrawFramebuffer();
+		if(!framebuffer)
+		{
+			return error(GL_INVALID_FRAMEBUFFER_OPERATION);
+		}
 		egl::Image *depthbuffer = framebuffer->getDepthBuffer();
 
 		if(depthbuffer)
@@ -3461,6 +3503,10 @@
 	if(mState.stencilWritemask && !mState.rasterizerDiscardEnabled)
 	{
 		Framebuffer *framebuffer = getDrawFramebuffer();
+		if(!framebuffer)
+		{
+			return error(GL_INVALID_FRAMEBUFFER_OPERATION);
+		}
 		egl::Image *stencilbuffer = framebuffer->getStencilBuffer();
 
 		if(stencilbuffer)
@@ -3946,8 +3992,8 @@
 	int readBufferWidth, readBufferHeight, readBufferSamples;
 	int drawBufferWidth, drawBufferHeight, drawBufferSamples;
 
-	if(!readFramebuffer || readFramebuffer->completeness(readBufferWidth, readBufferHeight, readBufferSamples) != GL_FRAMEBUFFER_COMPLETE ||
-	   !drawFramebuffer || drawFramebuffer->completeness(drawBufferWidth, drawBufferHeight, drawBufferSamples) != GL_FRAMEBUFFER_COMPLETE)
+	if(!readFramebuffer || (readFramebuffer->completeness(readBufferWidth, readBufferHeight, readBufferSamples) != GL_FRAMEBUFFER_COMPLETE) ||
+	   !drawFramebuffer || (drawFramebuffer->completeness(drawBufferWidth, drawBufferHeight, drawBufferSamples) != GL_FRAMEBUFFER_COMPLETE))
 	{
 		return error(GL_INVALID_FRAMEBUFFER_OPERATION);
 	}
@@ -4387,6 +4433,7 @@
 		"GL_OES_packed_depth_stencil",
 		"GL_OES_rgb8_rgba8",
 		"GL_OES_standard_derivatives",
+		"GL_OES_surfaceless_context",
 		"GL_OES_texture_float",
 		"GL_OES_texture_float_linear",
 		"GL_OES_texture_half_float",
diff --git a/src/OpenGL/libGLESv2/libGLESv2.cpp b/src/OpenGL/libGLESv2/libGLESv2.cpp
index 8fb198f..34b3db0 100644
--- a/src/OpenGL/libGLESv2/libGLESv2.cpp
+++ b/src/OpenGL/libGLESv2/libGLESv2.cpp
@@ -628,6 +628,11 @@
 			framebuffer = context->getDrawFramebuffer();
 		}
 
+		if(!framebuffer)
+		{
+			return GL_FRAMEBUFFER_UNDEFINED_OES;
+		}
+
 		return framebuffer->completeness();
 	}
 
@@ -956,7 +961,7 @@
 
 		es2::Framebuffer *framebuffer = context->getReadFramebuffer();
 
-		if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
+		if(!framebuffer || (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE))
 		{
 			return error(GL_INVALID_FRAMEBUFFER_OPERATION);
 		}
@@ -1067,7 +1072,7 @@
 	{
 		es2::Framebuffer *framebuffer = context->getReadFramebuffer();
 
-		if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
+		if(!framebuffer || (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE))
 		{
 			return error(GL_INVALID_FRAMEBUFFER_OPERATION);
 		}
@@ -2776,6 +2781,11 @@
 
 		es2::Framebuffer *framebuffer = context->getFramebuffer(framebufferName);
 
+		if(!framebuffer)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
 		GLenum attachmentType;
 		GLuint attachmentHandle;
 		GLint attachmentLayer;
@@ -6359,7 +6369,7 @@
 	{
 		es2::Framebuffer *framebuffer = context->getReadFramebuffer();
 
-		if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
+		if(!framebuffer || (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE))
 		{
 			return error(GL_INVALID_FRAMEBUFFER_OPERATION);
 		}
diff --git a/src/OpenGL/libGLESv2/libGLESv3.cpp b/src/OpenGL/libGLESv2/libGLESv3.cpp
index a985793..e048749 100644
--- a/src/OpenGL/libGLESv2/libGLESv3.cpp
+++ b/src/OpenGL/libGLESv2/libGLESv3.cpp
@@ -471,7 +471,7 @@
 	{
 		es2::Framebuffer *framebuffer = context->getReadFramebuffer();
 
-		if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
+		if(!framebuffer || (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE))
 		{
 			return error(GL_INVALID_FRAMEBUFFER_OPERATION);
 		}