Don't acquire image for copying until needed.

Bug chromium:849217

Change-Id: I69d2269c117500d21e5d0860aed0acea212948ba
Reviewed-on: https://swiftshader-review.googlesource.com/19268
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
diff --git a/src/OpenGL/libGL/Texture.cpp b/src/OpenGL/libGL/Texture.cpp
index 70ff9b2..3ff0cb3 100644
--- a/src/OpenGL/libGL/Texture.cpp
+++ b/src/OpenGL/libGL/Texture.cpp
@@ -412,14 +412,6 @@
 
 void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
 {
-	Image *renderTarget = source->getRenderTarget();
-
-	if(!renderTarget)
-	{
-		ERR("Failed to retrieve the render target.");
-		return error(GL_OUT_OF_MEMORY);
-	}
-
 	if(image[level])
 	{
 		image[level]->unbind();
@@ -434,13 +426,21 @@
 
 	if(width != 0 && height != 0)
 	{
+		Image *renderTarget = source->getRenderTarget();
+
+		if(!renderTarget)
+		{
+			ERR("Failed to retrieve the render target.");
+			return error(GL_OUT_OF_MEMORY);
+		}
+
 		sw::Rect sourceRect = {x, y, x + width, y + height};
 		sourceRect.clip(0, 0, source->getColorbuffer()->getWidth(), source->getColorbuffer()->getHeight());
 
 		copy(renderTarget, sourceRect, format, 0, 0, image[level]);
-	}
 
-	renderTarget->release();
+		renderTarget->release();
+	}
 }
 
 void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
@@ -896,14 +896,6 @@
 
 void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
 {
-	Image *renderTarget = source->getRenderTarget();
-
-	if(!renderTarget)
-	{
-		ERR("Failed to retrieve the render target.");
-		return error(GL_OUT_OF_MEMORY);
-	}
-
 	int face = CubeFaceIndex(target);
 
 	if(image[face][level])
@@ -920,13 +912,21 @@
 
 	if(width != 0 && height != 0)
 	{
+		Image *renderTarget = source->getRenderTarget();
+
+		if(!renderTarget)
+		{
+			ERR("Failed to retrieve the render target.");
+			return error(GL_OUT_OF_MEMORY);
+		}
+
 		sw::Rect sourceRect = {x, y, x + width, y + height};
 		sourceRect.clip(0, 0, source->getColorbuffer()->getWidth(), source->getColorbuffer()->getHeight());
 
 		copy(renderTarget, sourceRect, format, 0, 0, image[face][level]);
-	}
 
-	renderTarget->release();
+		renderTarget->release();
+	}
 }
 
 Image *TextureCubeMap::getImage(int face, unsigned int level)
diff --git a/src/OpenGL/libGLES_CM/Texture.cpp b/src/OpenGL/libGLES_CM/Texture.cpp
index 05f1ebd..1043918 100644
--- a/src/OpenGL/libGLES_CM/Texture.cpp
+++ b/src/OpenGL/libGLES_CM/Texture.cpp
@@ -495,14 +495,6 @@
 
 void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
 {
-	egl::Image *renderTarget = source->getRenderTarget();
-
-	if(!renderTarget)
-	{
-		ERR("Failed to retrieve the render target.");
-		return error(GL_OUT_OF_MEMORY);
-	}
-
 	if(image[level])
 	{
 		image[level]->release();
@@ -517,13 +509,21 @@
 
 	if(width != 0 && height != 0)
 	{
+		egl::Image *renderTarget = source->getRenderTarget();
+
+		if(!renderTarget)
+		{
+			ERR("Failed to retrieve the render target.");
+			return error(GL_OUT_OF_MEMORY);
+		}
+
 		sw::Rect sourceRect = {x, y, x + width, y + height};
 		sourceRect.clip(0, 0, source->getColorbuffer()->getWidth(), source->getColorbuffer()->getHeight());
 
 		copy(renderTarget, sourceRect, format, 0, 0, image[level]);
-	}
 
-	renderTarget->release();
+		renderTarget->release();
+	}
 }
 
 void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
diff --git a/src/OpenGL/libGLESv2/Texture.cpp b/src/OpenGL/libGLESv2/Texture.cpp
index 82c68e4..ca28ed9 100644
--- a/src/OpenGL/libGLESv2/Texture.cpp
+++ b/src/OpenGL/libGLESv2/Texture.cpp
@@ -609,14 +609,6 @@
 
 void Texture2D::copyImage(GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source)
 {
-	egl::Image *renderTarget = source->getRenderTarget();
-
-	if(!renderTarget)
-	{
-		ERR("Failed to retrieve the render target.");
-		return error(GL_OUT_OF_MEMORY);
-	}
-
 	if(image[level])
 	{
 		image[level]->release();
@@ -631,13 +623,21 @@
 
 	if(width != 0 && height != 0)
 	{
+		egl::Image *renderTarget = source->getRenderTarget();
+
+		if(!renderTarget)
+		{
+			ERR("Failed to retrieve the render target.");
+			return error(GL_OUT_OF_MEMORY);
+		}
+
 		sw::SliceRect sourceRect(x, y, x + width, y + height, 0);
 		sourceRect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight());
 
 		copy(renderTarget, sourceRect, 0, 0, 0, image[level]);
-	}
 
-	renderTarget->release();
+		renderTarget->release();
+	}
 }
 
 void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source)
@@ -1248,14 +1248,6 @@
 
 void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source)
 {
-	egl::Image *renderTarget = source->getRenderTarget();
-
-	if(!renderTarget)
-	{
-		ERR("Failed to retrieve the render target.");
-		return error(GL_OUT_OF_MEMORY);
-	}
-
 	int face = CubeFaceIndex(target);
 
 	if(image[face][level])
@@ -1273,13 +1265,21 @@
 
 	if(width != 0 && height != 0)
 	{
+		egl::Image *renderTarget = source->getRenderTarget();
+
+		if(!renderTarget)
+		{
+			ERR("Failed to retrieve the render target.");
+			return error(GL_OUT_OF_MEMORY);
+		}
+
 		sw::SliceRect sourceRect(x, y, x + width, y + height, 0);
 		sourceRect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight());
 
 		copy(renderTarget, sourceRect, 0, 0, 0, image[face][level]);
-	}
 
-	renderTarget->release();
+		renderTarget->release();
+	}
 }
 
 egl::Image *TextureCubeMap::getImage(int face, unsigned int level)
@@ -1582,14 +1582,6 @@
 
 void Texture3D::copyImage(GLint level, GLenum internalformat, GLint x, GLint y, GLint z, GLsizei width, GLsizei height, GLsizei depth, Renderbuffer *source)
 {
-	egl::Image *renderTarget = source->getRenderTarget();
-
-	if(!renderTarget)
-	{
-		ERR("Failed to retrieve the render target.");
-		return error(GL_OUT_OF_MEMORY);
-	}
-
 	if(image[level])
 	{
 		image[level]->release();
@@ -1604,6 +1596,14 @@
 
 	if(width != 0 && height != 0 && depth != 0)
 	{
+		egl::Image *renderTarget = source->getRenderTarget();
+
+		if(!renderTarget)
+		{
+			ERR("Failed to retrieve the render target.");
+			return error(GL_OUT_OF_MEMORY);
+		}
+
 		sw::SliceRect sourceRect(x, y, x + width, y + height, z);
 		sourceRect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight());
 
@@ -1611,9 +1611,9 @@
 		{
 			copy(renderTarget, sourceRect, 0, 0, sliceZ, image[level]);
 		}
-	}
 
-	renderTarget->release();
+		renderTarget->release();
+	}
 }
 
 void Texture3D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source)