Refactor Renderer11 to accomodate pixel pack.

Splitting the readTextureData call allow a pack buffer read
to return asynchronously after the D3D11 CopySubresource call.

Refactoring patch only.

BUG=angle:511

Change-Id: I3459ddfa7b48497b25fb2f4890e1cc1341e2cf75
Reviewed-on: https://chromium-review.googlesource.com/193620
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Tested-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libGLESv2/renderer/d3d11/BufferStorage11.cpp b/src/libGLESv2/renderer/d3d11/BufferStorage11.cpp
index 4b9d30a..a7dc819 100644
--- a/src/libGLESv2/renderer/d3d11/BufferStorage11.cpp
+++ b/src/libGLESv2/renderer/d3d11/BufferStorage11.cpp
@@ -11,10 +11,30 @@
 #include "libGLESv2/main.h"
 #include "libGLESv2/renderer/d3d11/Renderer11.h"
 #include "libGLESv2/renderer/d3d11/formatutils11.h"
+#include "libGLESv2/Buffer.h"
 
 namespace rx
 {
 
+PackPixelsParams::PackPixelsParams()
+  : format(GL_NONE),
+    type(GL_NONE),
+    outputPitch(0),
+    packBuffer(NULL),
+    offset(0)
+{}
+
+PackPixelsParams::PackPixelsParams(const gl::Rectangle &areaIn, GLenum formatIn, GLenum typeIn, GLuint outputPitchIn,
+                                   const gl::PixelPackState &packIn, ptrdiff_t offsetIn)
+  : area(areaIn),
+    format(formatIn),
+    type(typeIn),
+    outputPitch(outputPitchIn),
+    packBuffer(packIn.pixelBuffer.get()),
+    pack(packIn.alignment, packIn.reverseRowOrder),
+    offset(offsetIn)
+{}
+
 namespace gl_d3d11
 {
 
diff --git a/src/libGLESv2/renderer/d3d11/BufferStorage11.h b/src/libGLESv2/renderer/d3d11/BufferStorage11.h
index 29c74aa..be0e1ea 100644
--- a/src/libGLESv2/renderer/d3d11/BufferStorage11.h
+++ b/src/libGLESv2/renderer/d3d11/BufferStorage11.h
@@ -10,6 +10,7 @@
 #define LIBGLESV2_RENDERER_BUFFERSTORAGE11_H_
 
 #include "libGLESv2/renderer/BufferStorage.h"
+#include "libGLESv2/angletypes.h"
 
 namespace rx
 {
@@ -26,6 +27,21 @@
     BUFFER_USAGE_UNIFORM,
 };
 
+struct PackPixelsParams
+{
+    PackPixelsParams();
+    PackPixelsParams(const gl::Rectangle &area, GLenum format, GLenum type, GLuint outputPitch,
+                     const gl::PixelPackState &pack, ptrdiff_t offset);
+
+    gl::Rectangle area;
+    GLenum format;
+    GLenum type;
+    GLuint outputPitch;
+    gl::Buffer *packBuffer;
+    gl::PixelPackState pack;
+    ptrdiff_t offset;
+};
+
 typedef size_t DataRevision;
 
 class BufferStorage11 : public BufferStorage
diff --git a/src/libGLESv2/renderer/d3d11/Renderer11.cpp b/src/libGLESv2/renderer/d3d11/Renderer11.cpp
index 3b4d0f5..25ea413 100644
--- a/src/libGLESv2/renderer/d3d11/Renderer11.cpp
+++ b/src/libGLESv2/renderer/d3d11/Renderer11.cpp
@@ -3403,14 +3403,26 @@
 
     SafeRelease(srcTex);
 
+    PackPixelsParams packParams(safeArea, format, type, outputPitch, pack, 0);
+    packPixels(stagingTex, packParams, pixels);
+
+    SafeRelease(stagingTex);
+}
+
+void Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams &params, void *pixelsOut)
+{
+    D3D11_TEXTURE2D_DESC textureDesc;
+    readTexture->GetDesc(&textureDesc);
+
     D3D11_MAPPED_SUBRESOURCE mapping;
-    mDeviceContext->Map(stagingTex, 0, D3D11_MAP_READ, 0, &mapping);
+    HRESULT hr = mDeviceContext->Map(readTexture, 0, D3D11_MAP_READ, 0, &mapping);
+    ASSERT(SUCCEEDED(hr));
 
     unsigned char *source;
     int inputPitch;
-    if (pack.reverseRowOrder)
+    if (params.pack.reverseRowOrder)
     {
-        source = static_cast<unsigned char*>(mapping.pData) + mapping.RowPitch * (safeArea.height - 1);
+        source = static_cast<unsigned char*>(mapping.pData) + mapping.RowPitch * (params.area.height - 1);
         inputPitch = -static_cast<int>(mapping.RowPitch);
     }
     else
@@ -3427,29 +3439,28 @@
 
     GLuint sourcePixelSize = gl::GetPixelBytes(sourceInternalFormat, clientVersion);
 
-    if (sourceFormat == format && sourceType == type)
+    if (sourceFormat == params.format && sourceType == params.type)
     {
-        // Direct copy possible
-        unsigned char *dest = static_cast<unsigned char*>(pixels);
-        for (int y = 0; y < safeArea.height; y++)
+        unsigned char *dest = static_cast<unsigned char*>(pixelsOut) + params.offset;
+        for (int y = 0; y < params.area.height; y++)
         {
-            memcpy(dest + y * outputPitch, source + y * inputPitch, safeArea.width * sourcePixelSize);
+            memcpy(dest + y * params.outputPitch, source + y * inputPitch, params.area.width * sourcePixelSize);
         }
     }
     else
     {
-        GLenum destInternalFormat = gl::GetSizedInternalFormat(format, type, clientVersion);
+        GLenum destInternalFormat = gl::GetSizedInternalFormat(params.format, params.type, clientVersion);
         GLuint destPixelSize = gl::GetPixelBytes(destInternalFormat, clientVersion);
 
-        ColorCopyFunction fastCopyFunc = d3d11::GetFastCopyFunction(textureDesc.Format, format, type);
+        ColorCopyFunction fastCopyFunc = d3d11::GetFastCopyFunction(textureDesc.Format, params.format, params.type);
         if (fastCopyFunc)
         {
             // Fast copy is possible through some special function
-            for (int y = 0; y < safeArea.height; y++)
+            for (int y = 0; y < params.area.height; y++)
             {
-                for (int x = 0; x < safeArea.width; x++)
+                for (int x = 0; x < params.area.width; x++)
                 {
-                    void *dest = static_cast<unsigned char*>(pixels) + y * outputPitch + x * destPixelSize;
+                    void *dest = static_cast<unsigned char*>(pixelsOut) + params.offset + y * params.outputPitch + x * destPixelSize;
                     void *src = static_cast<unsigned char*>(source) + y * inputPitch + x * sourcePixelSize;
 
                     fastCopyFunc(src, dest);
@@ -3459,18 +3470,18 @@
         else
         {
             ColorReadFunction readFunc = d3d11::GetColorReadFunction(textureDesc.Format);
-            ColorWriteFunction writeFunc = gl::GetColorWriteFunction(format, type, clientVersion);
+            ColorWriteFunction writeFunc = gl::GetColorWriteFunction(params.format, params.type, clientVersion);
 
             unsigned char temp[16]; // Maximum size of any Color<T> type used.
             META_ASSERT(sizeof(temp) >= sizeof(gl::ColorF)  &&
                         sizeof(temp) >= sizeof(gl::ColorUI) &&
                         sizeof(temp) >= sizeof(gl::ColorI));
 
-            for (int y = 0; y < safeArea.height; y++)
+            for (int y = 0; y < params.area.height; y++)
             {
-                for (int x = 0; x < safeArea.width; x++)
+                for (int x = 0; x < params.area.width; x++)
                 {
-                    void *dest = static_cast<unsigned char*>(pixels) + y * outputPitch + x * destPixelSize;
+                    void *dest = static_cast<unsigned char*>(pixelsOut) + params.offset + y * params.outputPitch + x * destPixelSize;
                     void *src = static_cast<unsigned char*>(source) + y * inputPitch + x * sourcePixelSize;
 
                     // readFunc and writeFunc will be using the same type of color, CopyTexImage
@@ -3482,9 +3493,7 @@
         }
     }
 
-    mDeviceContext->Unmap(stagingTex, 0);
-
-    SafeRelease(stagingTex);
+    mDeviceContext->Unmap(readTexture, 0);
 }
 
 bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget,
diff --git a/src/libGLESv2/renderer/d3d11/Renderer11.h b/src/libGLESv2/renderer/d3d11/Renderer11.h
index e208d65..4cfcc6d 100644
--- a/src/libGLESv2/renderer/d3d11/Renderer11.h
+++ b/src/libGLESv2/renderer/d3d11/Renderer11.h
@@ -33,6 +33,7 @@
 class Blit11;
 class Clear11;
 class PixelTransfer11;
+struct PackPixelsParams;
 
 enum
 {
@@ -231,6 +232,7 @@
     bool getRenderTargetResource(gl::Renderbuffer *colorbuffer, unsigned int *subresourceIndex, ID3D11Texture2D **resource);
     void unapplyRenderTargets();
     void setOneTimeRenderTarget(ID3D11RenderTargetView *renderTargetView);
+    void packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams &params, void *pixelsOut);
 
     virtual bool getLUID(LUID *adapterLuid) const;
     virtual GLenum getNativeTextureFormat(GLenum internalFormat) const;