From 54ace01cd6f962f1b43faed541e2f24510cf470d Mon Sep 17 00:00:00 2001
From: Sam Cake <Sam Cake>
Date: Tue, 2 May 2017 00:32:32 -0700
Subject: [PATCH] Factorizing the code on both 45 and 41 backend

---
 .../src/gpu/gl41/GL41BackendTexture.cpp       | 46 +++++++-------
 .../gpu/gl45/GL45BackendVariableTexture.cpp   | 63 ++++++++++---------
 2 files changed, 53 insertions(+), 56 deletions(-)

diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp
index e52c2398f9..114f61dfc9 100644
--- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp
+++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp
@@ -374,17 +374,18 @@ void copyCompressedTexGPUMem(const gpu::Texture& texture, GLenum texTarget, GLui
         uint16_t sourceLevel = mip - srcAllocatedMip;
 
         // Grab internal format once
-        if (internalFormat != 0) {
+        if (internalFormat == 0) {
             glGetTexLevelParameteriv(faceTargets[0], sourceLevel, GL_TEXTURE_INTERNAL_FORMAT, &internalFormat);
         }
 
         // Collect the size of the first face, and then compute the total size offset needed for this mip level
-        auto mipDimensions = texture.evalMipDimensions(sourceLevel);
+        auto mipDimensions = texture.evalMipDimensions(mip);
         sourceMip._width = mipDimensions.x;
         sourceMip._height = mipDimensions.y;
-
-   //     glGetTexLevelParameteriv(faceTargets.front(), sourceLevel, GL_TEXTURE_WIDTH, &sourceMip._width);
-   //     glGetTexLevelParameteriv(faceTargets.front(), sourceLevel, GL_TEXTURE_HEIGHT, &sourceMip._height);
+#ifdef DEBUG_COPY
+        glGetTexLevelParameteriv(faceTargets.front(), sourceLevel, GL_TEXTURE_WIDTH, &sourceMip._width);
+        glGetTexLevelParameteriv(faceTargets.front(), sourceLevel, GL_TEXTURE_HEIGHT, &sourceMip._height);
+#endif
         glGetTexLevelParameteriv(faceTargets.front(), sourceLevel, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &sourceMip._faceSize);
         sourceMip._size = (GLint)faceTargets.size() * sourceMip._faceSize;
         sourceMip._offset = bufferOffset;
@@ -394,21 +395,12 @@ void copyCompressedTexGPUMem(const gpu::Texture& texture, GLenum texTarget, GLui
     (void)CHECK_GL_ERROR();
 
     // Allocate the PBO to accomodate for all the mips to copy
-#ifdef USE_PBO
-    GLvoid* pboPointer = 0;
+    GLint pboPointer = 0;
     GLuint pbo { 0 };
     glGenBuffers(1, &pbo);
     glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo);
     glBufferData(GL_PIXEL_PACK_BUFFER, bufferOffset, nullptr, GL_STREAM_COPY);
     (void)CHECK_GL_ERROR();
-    gpu::gl::checkGLError();
-#else
-    glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
-    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
-    bytes.resize(bufferOffset);
-    auto pboPointer = bytes.data();
-#endif
-
 
     // Transfer from source texture to pbo
     for (uint16_t mip = populatedMips; mip < numMips; ++mip) {
@@ -417,18 +409,15 @@ void copyCompressedTexGPUMem(const gpu::Texture& texture, GLenum texTarget, GLui
         uint16_t sourceLevel = mip - srcAllocatedMip;
 
         for (GLint f = 0; f < faceTargets.size(); f++) {
-            glGetCompressedTexImage(faceTargets[f], sourceLevel, (void*) (pboPointer + (sourceMip._offset + f * sourceMip._faceSize)));
+             glGetCompressedTexImage(faceTargets[f], sourceLevel, (void*) (pboPointer + (sourceMip._offset + f * sourceMip._faceSize)));
         }
         (void)CHECK_GL_ERROR();
-        gpu::gl::checkGLError();
     }
 
     // Now populate the new texture from the pbo
     glBindTexture(texTarget, 0);
-#ifdef USE_PBO
     glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
-#endif
 
     glActiveTexture(GL_TEXTURE0 + GL41Backend::RESOURCE_TRANSFER_TEX_UNIT);
     glBindTexture(texTarget, destId);
@@ -440,17 +429,21 @@ void copyCompressedTexGPUMem(const gpu::Texture& texture, GLenum texTarget, GLui
         uint16_t destLevel = mip - destAllocatedMip;
 
         for (GLint f = 0; f < faceTargets.size(); f++) {
-            glCompressedTexSubImage2D(faceTargets[f], destLevel,0, 0, sourceMip._width, sourceMip._height, internalFormat,
+#ifdef DEBUG_COPY
+            GLint destWidth, destHeight, destSize;
+            glGetTexLevelParameteriv(faceTargets.front(), destLevel, GL_TEXTURE_WIDTH, &destWidth);
+            glGetTexLevelParameteriv(faceTargets.front(), destLevel, GL_TEXTURE_HEIGHT, &destHeight);
+            glGetTexLevelParameteriv(faceTargets.front(), destLevel, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &destSize);
+#endif
+            glCompressedTexSubImage2D(faceTargets[f], destLevel, 0, 0, sourceMip._width, sourceMip._height, internalFormat,
                 sourceMip._faceSize, (void*)(pboPointer + (sourceMip._offset + f * sourceMip._faceSize)));
             gpu::gl::checkGLError();
         }
     }
 
-#ifdef USE_PBO
     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
     glDeleteBuffers(1, &pbo);
 #endif
-#endif
 }
 
 void GL41VariableAllocationTexture::promote() {
@@ -462,15 +455,16 @@ void GL41VariableAllocationTexture::promote() {
 
     GLuint oldId = _id;
     auto oldSize = _size;
+    uint16_t oldAllocatedMip = _allocatedMip;
+
     // create new texture
     const_cast<GLuint&>(_id) = allocate(_gpuObject);
-    uint16_t oldAllocatedMip = _allocatedMip;
 
     // allocate storage for new level
     allocateStorage(targetAllocatedMip);
 
+    // copy pre-existing mips
     uint16_t numMips = _gpuObject.getNumMips();
-
     if (_texelFormat.isCompressed()) {
         withPreservedTexture([&] {
             copyCompressedTexGPUMem(_gpuObject, _target, oldId, _id, numMips, oldAllocatedMip, _allocatedMip, _populatedMip);
@@ -495,13 +489,15 @@ void GL41VariableAllocationTexture::demote() {
     Q_ASSERT(_allocatedMip < _maxAllocatedMip);
     auto oldId = _id;
     auto oldSize = _size;
+
+    // allocate new texture
     const_cast<GLuint&>(_id) = allocate(_gpuObject);
     uint16_t oldAllocatedMip = _allocatedMip;
     allocateStorage(_allocatedMip + 1);
     _populatedMip = std::max(_populatedMip, _allocatedMip);
 
+    // copy pre-existing mips
     uint16_t numMips = _gpuObject.getNumMips();
-
     if (_texelFormat.isCompressed()) {
         withPreservedTexture([&] {
             copyCompressedTexGPUMem(_gpuObject, _target, oldId, _id, numMips, oldAllocatedMip, _allocatedMip, _populatedMip);
diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp
index 92d820e5f0..3381fa8cce 100644
--- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp
+++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp
@@ -97,6 +97,24 @@ void GL45ResourceTexture::syncSampler() const {
     glTextureParameteri(_id, GL_TEXTURE_BASE_LEVEL, _populatedMip - _allocatedMip);
 }
 
+
+void copyTexGPUMem(const gpu::Texture& texture, GLenum texTarget, GLuint srcId, GLuint destId, uint16_t numMips, uint16_t srcAllocatedMip, uint16_t destAllocatedMip, uint16_t populatedMips) {
+    for (uint16_t mip = populatedMips; mip < numMips; ++mip) {
+        auto mipDimensions = texture.evalMipDimensions(mip);
+        uint16_t targetMip = mip - destAllocatedMip;
+        uint16_t sourceMip = mip - srcAllocatedMip;
+        auto faces = GLTexture::getFaceCount(texTarget);
+        for (uint8_t face = 0; face < faces; ++face) {
+            glCopyImageSubData(
+                srcId, texTarget, sourceMip, 0, 0, face,
+                destId, texTarget, targetMip, 0, 0, face,
+                mipDimensions.x, mipDimensions.y, 1
+                );
+            (void)CHECK_GL_ERROR();
+        }
+    }
+}
+
 void GL45ResourceTexture::promote() {
     PROFILE_RANGE(render_gpu_gl, __FUNCTION__);
     Q_ASSERT(_allocatedMip > 0);
@@ -106,27 +124,18 @@ void GL45ResourceTexture::promote() {
 
     GLuint oldId = _id;
     auto oldSize = _size;
+    uint16_t oldAllocatedMip = _allocatedMip;
+
     // create new texture
     const_cast<GLuint&>(_id) = allocate(_gpuObject);
-    uint16_t oldAllocatedMip = _allocatedMip;
+
     // allocate storage for new level
     allocateStorage(targetAllocatedMip);
-    uint16_t mips = _gpuObject.getNumMips();
+    
     // copy pre-existing mips
-    for (uint16_t mip = _populatedMip; mip < mips; ++mip) {
-        auto mipDimensions = _gpuObject.evalMipDimensions(mip);
-        uint16_t targetMip = mip - _allocatedMip;
-        uint16_t sourceMip = mip - oldAllocatedMip;
-        auto faces = getFaceCount(_target);
-        for (uint8_t face = 0; face < faces; ++face) {
-            glCopyImageSubData(
-                oldId, _target, sourceMip, 0, 0, face,
-                _id, _target, targetMip, 0, 0, face,
-                mipDimensions.x, mipDimensions.y, 1
-                );
-            (void)CHECK_GL_ERROR();
-        }
-    }
+    uint16_t numMips = _gpuObject.getNumMips();
+    copyTexGPUMem(_gpuObject, _target, _id, oldId, numMips, oldAllocatedMip, _allocatedMip, _populatedMip);
+
     // destroy the old texture
     glDeleteTextures(1, &oldId);
     // update the memory usage
@@ -140,25 +149,17 @@ void GL45ResourceTexture::demote() {
     Q_ASSERT(_allocatedMip < _maxAllocatedMip);
     auto oldId = _id;
     auto oldSize = _size;
+
+    // allocate new texture
     const_cast<GLuint&>(_id) = allocate(_gpuObject);
+    uint16_t oldAllocatedMip = _allocatedMip;
     allocateStorage(_allocatedMip + 1);
     _populatedMip = std::max(_populatedMip, _allocatedMip);
-    uint16_t mips = _gpuObject.getNumMips();
+
     // copy pre-existing mips
-    for (uint16_t mip = _populatedMip; mip < mips; ++mip) {
-        auto mipDimensions = _gpuObject.evalMipDimensions(mip);
-        uint16_t targetMip = mip - _allocatedMip;
-        uint16_t sourceMip = targetMip + 1;
-        auto faces = getFaceCount(_target);
-        for (uint8_t face = 0; face < faces; ++face) {
-            glCopyImageSubData(
-                oldId, _target, sourceMip, 0, 0, face,
-                _id, _target, targetMip, 0, 0, face,
-                mipDimensions.x, mipDimensions.y, 1
-            );
-            (void)CHECK_GL_ERROR();
-        }
-    }
+    uint16_t numMips = _gpuObject.getNumMips();
+    copyTexGPUMem(_gpuObject, _target, _id, oldId, numMips, oldAllocatedMip, _allocatedMip, _populatedMip);
+
     // destroy the old texture
     glDeleteTextures(1, &oldId);
     // update the memory usage