diff options
author | Lingfeng Yang <lfy@google.com> | 2020-06-13 04:26:31 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2020-06-13 04:26:31 +0000 |
commit | 0f137cb2f4395006a06040eb269779d63b6fd24b (patch) | |
tree | 7eb1820d616b7fab6cfd514fde1c52638f89e382 | |
parent | ef96b45bad48bab8c058c2f188b682a7912a41a7 (diff) | |
parent | b54151909cf2060ab97074a7c2acadc243640ee8 (diff) | |
download | goldfish-opengl-0f137cb2f4395006a06040eb269779d63b6fd24b.tar.gz |
Account for row slack in upload/download of textures am: b54151909c
Original change: https://googleplex-android-review.googlesource.com/c/device/generic/goldfish-opengl/+/11854592
Change-Id: Ib51bcfdf30da0f775131e537da52ba0b8c5e7d84
-rw-r--r-- | host/include/libOpenglRender/IOStream.h | 2 | ||||
-rw-r--r-- | shared/OpenglCodecCommon/GLClientState.cpp | 35 | ||||
-rw-r--r-- | shared/OpenglCodecCommon/GLClientState.h | 5 | ||||
-rw-r--r-- | shared/OpenglCodecCommon/GLESTextureUtils.cpp | 41 | ||||
-rw-r--r-- | shared/OpenglCodecCommon/GLESTextureUtils.h | 18 | ||||
-rw-r--r-- | system/GLESv2_enc/IOStream2.cpp | 208 | ||||
-rw-r--r-- | system/GLESv2_enc/gl2_enc.cpp | 8 |
7 files changed, 259 insertions, 58 deletions
diff --git a/host/include/libOpenglRender/IOStream.h b/host/include/libOpenglRender/IOStream.h index 93954abc..9173d317 100644 --- a/host/include/libOpenglRender/IOStream.h +++ b/host/include/libOpenglRender/IOStream.h @@ -97,7 +97,7 @@ public: // outside of GLESv2_enc will produce a link error. This is intentional // (technical debt). void readbackPixels(void* context, int width, int height, unsigned int format, unsigned int type, void* pixels); - void uploadPixels(void* context, int width, int height, unsigned int format, unsigned int type, const void* pixels); + void uploadPixels(void* context, int width, int height, int depth, unsigned int format, unsigned int type, const void* pixels); private: diff --git a/shared/OpenglCodecCommon/GLClientState.cpp b/shared/OpenglCodecCommon/GLClientState.cpp index 3f207b8e..a31f6975 100644 --- a/shared/OpenglCodecCommon/GLClientState.cpp +++ b/shared/OpenglCodecCommon/GLClientState.cpp @@ -852,7 +852,7 @@ size_t GLClientState::clearBufferNumElts(GLenum buffer) const return 1; } -void GLClientState::getPackingOffsets2D(GLsizei width, GLsizei height, GLenum format, GLenum type, int* startOffset, int* pixelRowSize, int* totalRowSize, int* skipRows) const +void GLClientState::getPackingOffsets2D(GLsizei width, GLsizei height, GLenum format, GLenum type, int* bpp, int* startOffset, int* pixelRowSize, int* totalRowSize, int* skipRows) const { if (width <= 0 || height <= 0) { *startOffset = 0; @@ -868,6 +868,7 @@ void GLClientState::getPackingOffsets2D(GLsizei width, GLsizei height, GLenum fo m_pixelStore.pack_row_length, m_pixelStore.pack_skip_pixels, m_pixelStore.pack_skip_rows, + bpp, startOffset, pixelRowSize, totalRowSize); @@ -875,7 +876,7 @@ void GLClientState::getPackingOffsets2D(GLsizei width, GLsizei height, GLenum fo *skipRows = m_pixelStore.pack_skip_rows; } -void GLClientState::getUnpackingOffsets2D(GLsizei width, GLsizei height, GLenum format, GLenum type, int* startOffset, int* pixelRowSize, int* totalRowSize, int* skipRows) const +void GLClientState::getUnpackingOffsets2D(GLsizei width, GLsizei height, GLenum format, GLenum type, int* bpp, int* startOffset, int* pixelRowSize, int* totalRowSize, int* skipRows) const { if (width <= 0 || height <= 0) { *startOffset = 0; @@ -891,6 +892,7 @@ void GLClientState::getUnpackingOffsets2D(GLsizei width, GLsizei height, GLenum m_pixelStore.unpack_row_length, m_pixelStore.unpack_skip_pixels, m_pixelStore.unpack_skip_rows, + bpp, startOffset, pixelRowSize, totalRowSize); @@ -898,6 +900,35 @@ void GLClientState::getUnpackingOffsets2D(GLsizei width, GLsizei height, GLenum *skipRows = m_pixelStore.unpack_skip_rows; } +void GLClientState::getUnpackingOffsets3D(GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, int* bpp, int* startOffset, int* pixelRowSize, int* totalRowSize, int* pixelImageSize, int* totalImageSize, int* skipRows, int* skipImages) const +{ + if (width <= 0 || height <= 0) { + *startOffset = 0; + *pixelRowSize = 0; + *totalRowSize = 0; + return; + } + + GLESTextureUtils::computePackingOffsets3D( + width, height, depth, + format, type, + m_pixelStore.unpack_alignment, + m_pixelStore.unpack_row_length, + m_pixelStore.unpack_image_height, + m_pixelStore.unpack_skip_pixels, + m_pixelStore.unpack_skip_rows, + m_pixelStore.unpack_skip_images, + bpp, + startOffset, + pixelRowSize, + totalRowSize, + pixelImageSize, + totalImageSize); + + *skipRows = m_pixelStore.unpack_skip_rows; + *skipImages = m_pixelStore.unpack_skip_images; +} + void GLClientState::setNumActiveUniformsInUniformBlock(GLuint program, GLuint uniformBlockIndex, GLint numActiveUniforms) { UniformBlockInfoKey key; key.program = program; diff --git a/shared/OpenglCodecCommon/GLClientState.h b/shared/OpenglCodecCommon/GLClientState.h index f9f8ee3d..b7f56559 100644 --- a/shared/OpenglCodecCommon/GLClientState.h +++ b/shared/OpenglCodecCommon/GLClientState.h @@ -253,8 +253,9 @@ public: size_t pixelDataSize(GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, int pack) const; size_t pboNeededDataSize(GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, int pack) const; size_t clearBufferNumElts(GLenum buffer) const; - void getPackingOffsets2D(GLsizei width, GLsizei height, GLenum format, GLenum type, int* startOffset, int* pixelRowSize, int* totalRowSize, int* skipRows) const; - void getUnpackingOffsets2D(GLsizei width, GLsizei height, GLenum format, GLenum type, int* startOffset, int* pixelRowSize, int* totalRowSize, int* skipRows) const; + void getPackingOffsets2D(GLsizei width, GLsizei height, GLenum format, GLenum type, int* bpp, int* startOffset, int* pixelRowSize, int* totalRowSize, int* skipRows) const; + void getUnpackingOffsets2D(GLsizei width, GLsizei height, GLenum format, GLenum type, int* bpp, int* startOffset, int* pixelRowSize, int* totalRowSize, int* skipRows) const; + void getUnpackingOffsets3D(GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, int* bpp, int* startOffset, int* pixelRowSize, int* totalRowSize, int* pixelImageSize, int* totalImageSize, int* skipRows, int* skipImages) const; void setCurrentProgram(GLint program) { m_currentProgram = program; } void setCurrentShaderProgram(GLint program) { m_currentShaderProgram = program; } diff --git a/shared/OpenglCodecCommon/GLESTextureUtils.cpp b/shared/OpenglCodecCommon/GLESTextureUtils.cpp index 297a862f..cedcda86 100644 --- a/shared/OpenglCodecCommon/GLESTextureUtils.cpp +++ b/shared/OpenglCodecCommon/GLESTextureUtils.cpp @@ -207,7 +207,9 @@ static int computePackingOffset(GLenum format, GLenum type, GLsizei width, GLsiz GLsizei alignedPitch = computePitch(width, format, type, align); int packingOffsetRows = (skipImages * height + skipRows); - return packingOffsetRows * alignedPitch + skipPixels * computePixelSize(format, type); + int res = packingOffsetRows * alignedPitch + skipPixels * computePixelSize(format, type); + + return res; } void computeTextureStartEnd( @@ -295,6 +297,7 @@ void computePackingOffsets2D( int packRowLength, int packSkipPixels, int packSkipRows, + int* bpp, int* startOffset, int* packingPixelRowSize, int* packingTotalRowSize) { @@ -307,10 +310,46 @@ void computePackingOffsets2D( computePackingOffset( format, type, widthTotal, height, packAlignment, packSkipPixels, packSkipRows, 0 /* skip images = 0 */); + if (bpp) *bpp = computePixelSize(format, type); if (startOffset) *startOffset = packingOffsetStart; if (packingPixelRowSize) *packingPixelRowSize = pixelsOnlyRowSize; if (packingTotalRowSize) *packingTotalRowSize = totalRowSize; } +void computePackingOffsets3D( + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, + int packAlignment, + int packRowLength, + int packImageHeight, + int packSkipPixels, + int packSkipRows, + int packSkipImages, + int* bpp, + int* startOffset, + int* packingPixelRowSize, + int* packingTotalRowSize, + int* packingPixelImageSize, + int* packingTotalImageSize) { + + int widthTotal = (packRowLength == 0) ? width : packRowLength; + int totalRowSize = computePitch(widthTotal, format, type, packAlignment); + int pixelsOnlyRowSize = computePitch(width, format, type, packAlignment); + + int heightTotal = packImageHeight == 0 ? height : packImageHeight; + int totalImageSize = totalRowSize * heightTotal; + int pixelsOnlyImageSize = totalRowSize * height; + + int packingOffsetStart = + computePackingOffset( + format, type, widthTotal, heightTotal, packAlignment, packSkipPixels, packSkipRows, packSkipImages); + + if (bpp) *bpp = computePixelSize(format, type); + if (startOffset) *startOffset = packingOffsetStart; + if (packingPixelRowSize) *packingPixelRowSize = pixelsOnlyRowSize; + if (packingTotalRowSize) *packingTotalRowSize = totalRowSize; + if (packingPixelImageSize) *packingPixelImageSize = pixelsOnlyImageSize; + if (packingTotalImageSize) *packingTotalImageSize = totalImageSize; +} } // namespace GLESTextureUtils diff --git a/shared/OpenglCodecCommon/GLESTextureUtils.h b/shared/OpenglCodecCommon/GLESTextureUtils.h index f623d23b..1d26b3a5 100644 --- a/shared/OpenglCodecCommon/GLESTextureUtils.h +++ b/shared/OpenglCodecCommon/GLESTextureUtils.h @@ -49,9 +49,27 @@ void computePackingOffsets2D( int packRowLength, int packSkipPixels, int packSkipRows, + int* bpp, int* startOffset, int* packingPixelRowSize, int* packingTotalRowSize); +// For processing 3D textures exactly to the sizes of client buffers. +void computePackingOffsets3D( + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, + int packAlignment, + int packRowLength, + int packImageHeight, + int packSkipPixels, + int packSkipRows, + int packSkipImages, + int* bpp, + int* startOffset, + int* packingPixelRowSize, + int* packingTotalRowSize, + int* packingPixelImageSize, + int* packingTotalImageSize); + } // namespace GLESTextureUtils #endif diff --git a/system/GLESv2_enc/IOStream2.cpp b/system/GLESv2_enc/IOStream2.cpp index 1362d3e1..4890852b 100644 --- a/system/GLESv2_enc/IOStream2.cpp +++ b/system/GLESv2_enc/IOStream2.cpp @@ -12,12 +12,14 @@ void IOStream::readbackPixels(void* context, int width, int height, unsigned int GL2Encoder *ctx = (GL2Encoder *)context; assert (ctx->state() != NULL); + int bpp = 0; int startOffset = 0; int pixelRowSize = 0; int totalRowSize = 0; int skipRows = 0; ctx->state()->getPackingOffsets2D(width, height, format, type, + &bpp, &startOffset, &pixelRowSize, &totalRowSize, @@ -31,7 +33,7 @@ void IOStream::readbackPixels(void* context, int width, int height, unsigned int pixelRowSize == totalRowSize) { // fast path readback(pixels, pixelDataSize); - } else if (pixelRowSize == totalRowSize) { + } else if (pixelRowSize == totalRowSize && (pixelRowSize == width * bpp)) { // fast path but with skip in the beginning std::vector<char> paddingToDiscard(startOffset, 0); readback(&paddingToDiscard[0], startOffset); @@ -51,63 +53,173 @@ void IOStream::readbackPixels(void* context, int width, int height, unsigned int char* start = (char*)pixels + startOffset; for (int i = 0; i < height; i++) { - readback(start, pixelRowSize); - totalReadback += pixelRowSize; - readback(&paddingToDiscard[0], paddingSize); - totalReadback += paddingSize; - start += totalRowSize; + if (pixelRowSize != width * bpp) { + size_t rowSlack = pixelRowSize - width * bpp; + std::vector<char> rowSlackToDiscard(rowSlack, 0); + readback(start, width * bpp); + readback(&rowSlackToDiscard[0], rowSlack); + totalReadback += pixelRowSize; + readback(&paddingToDiscard[0], paddingSize); + totalReadback += paddingSize; + start += totalRowSize; + } else { + readback(start, pixelRowSize); + totalReadback += pixelRowSize; + readback(&paddingToDiscard[0], paddingSize); + totalReadback += paddingSize; + start += totalRowSize; + } } } } -void IOStream::uploadPixels(void* context, int width, int height, unsigned int format, unsigned int type, const void* pixels) { +void IOStream::uploadPixels(void* context, int width, int height, int depth, unsigned int format, unsigned int type, const void* pixels) { GL2Encoder *ctx = (GL2Encoder *)context; assert (ctx->state() != NULL); - int startOffset = 0; - int pixelRowSize = 0; - int totalRowSize = 0; - int skipRows = 0; - - ctx->state()->getUnpackingOffsets2D(width, height, format, type, - &startOffset, - &pixelRowSize, - &totalRowSize, - &skipRows); - - size_t pixelDataSize = - ctx->state()->pixelDataSize( - width, height, 1, format, type, 0 /* is unpack */); - - if (startOffset == 0 && - pixelRowSize == totalRowSize) { - // fast path - writeFully(pixels, pixelDataSize); - } else if (pixelRowSize == totalRowSize) { - // fast path but with skip in the beginning - std::vector<char> paddingToDiscard(startOffset, 0); - writeFully(&paddingToDiscard[0], startOffset); - writeFully((char*)pixels + startOffset, pixelDataSize - startOffset); - } else { - int totalReadback = 0; - - if (startOffset > 0) { + if (1 == depth) { + int bpp = 0; + int startOffset = 0; + int pixelRowSize = 0; + int totalRowSize = 0; + int skipRows = 0; + + ctx->state()->getUnpackingOffsets2D(width, height, format, type, + &bpp, + &startOffset, + &pixelRowSize, + &totalRowSize, + &skipRows); + + size_t pixelDataSize = + ctx->state()->pixelDataSize( + width, height, 1, format, type, 0 /* is unpack */); + + if (startOffset == 0 && + pixelRowSize == totalRowSize) { + // fast path + writeFully(pixels, pixelDataSize); + } else if (pixelRowSize == totalRowSize && (pixelRowSize == width * bpp)) { + // fast path but with skip in the beginning std::vector<char> paddingToDiscard(startOffset, 0); writeFully(&paddingToDiscard[0], startOffset); - totalReadback += startOffset; + writeFully((char*)pixels + startOffset, pixelDataSize - startOffset); + } else { + int totalReadback = 0; + + if (startOffset > 0) { + std::vector<char> paddingToDiscard(startOffset, 0); + writeFully(&paddingToDiscard[0], startOffset); + totalReadback += startOffset; + } + // need to upload row by row + size_t paddingSize = totalRowSize - pixelRowSize; + std::vector<char> paddingToDiscard(paddingSize, 0); + + char* start = (char*)pixels + startOffset; + + for (int i = 0; i < height; i++) { + if (pixelRowSize != width * bpp) { + size_t rowSlack = pixelRowSize - width * bpp; + std::vector<char> rowSlackToDiscard(rowSlack, 0); + writeFully(start, width * bpp); + writeFully(&rowSlackToDiscard[0], rowSlack); + totalReadback += pixelRowSize; + writeFully(&paddingToDiscard[0], paddingSize); + totalReadback += paddingSize; + start += totalRowSize; + } else { + writeFully(start, pixelRowSize); + totalReadback += pixelRowSize; + writeFully(&paddingToDiscard[0], paddingSize); + totalReadback += paddingSize; + start += totalRowSize; + } + } } - // need to upload row by row - size_t paddingSize = totalRowSize - pixelRowSize; - std::vector<char> paddingToDiscard(paddingSize, 0); - - char* start = (char*)pixels + startOffset; - - for (int i = 0; i < height; i++) { - writeFully(start, pixelRowSize); - totalReadback += pixelRowSize; - writeFully(&paddingToDiscard[0], paddingSize); - totalReadback += paddingSize; - start += totalRowSize; + } else { + int bpp = 0; + int startOffset = 0; + int pixelRowSize = 0; + int totalRowSize = 0; + int pixelImageSize = 0; + int totalImageSize = 0; + int skipRows = 0; + int skipImages = 0; + + ctx->state()->getUnpackingOffsets3D(width, height, depth, format, type, + &bpp, + &startOffset, + &pixelRowSize, + &totalRowSize, + &pixelImageSize, + &totalImageSize, + &skipRows, + &skipImages); + + size_t pixelDataSize = + ctx->state()->pixelDataSize( + width, height, depth, format, type, 0 /* is unpack */); + + size_t sent = 0; + + if (startOffset == 0 && + pixelRowSize == totalRowSize && + pixelImageSize == totalImageSize) { + // fast path + writeFully(pixels, pixelDataSize); + sent += pixelDataSize; + } else if (pixelRowSize == totalRowSize && + pixelImageSize == totalImageSize && + pixelRowSize == (width * bpp)) { + // fast path but with skip in the beginning + std::vector<char> paddingToDiscard(startOffset, 0); + writeFully(&paddingToDiscard[0], startOffset); + writeFully((char*)pixels + startOffset, pixelDataSize - startOffset); + sent += pixelDataSize; + } else { + int totalReadback = 0; + + if (startOffset > 0) { + std::vector<char> paddingToDiscard(startOffset, 0); + writeFully(&paddingToDiscard[0], startOffset); + totalReadback += startOffset; + } + // need to upload row by row + size_t paddingSize = totalRowSize - pixelRowSize; + std::vector<char> paddingToDiscard(paddingSize, 0); + + char* start = (char*)pixels + startOffset; + + size_t rowSlack = pixelRowSize - width * bpp; + std::vector<char> rowSlackToDiscard(rowSlack, 0); + + size_t imageSlack = totalImageSize - pixelImageSize; + std::vector<char> imageSlackToDiscard(imageSlack, 0); + + for (int k = 0; k < depth; ++k) { + for (int i = 0; i < height; i++) { + if (pixelRowSize != width * bpp) { + writeFully(start, width * bpp); + writeFully(&rowSlackToDiscard[0], rowSlack); + totalReadback += pixelRowSize; + writeFully(&paddingToDiscard[0], paddingSize); + totalReadback += paddingSize; + start += totalRowSize; + } else { + writeFully(start, pixelRowSize); + totalReadback += pixelRowSize; + writeFully(&paddingToDiscard[0], paddingSize); + totalReadback += paddingSize; + start += totalRowSize; + } + } + if (imageSlack > 0) { + writeFully(&imageSlackToDiscard[0], imageSlack); + start += imageSlack; + totalReadback += imageSlack; + } + } } } } diff --git a/system/GLESv2_enc/gl2_enc.cpp b/system/GLESv2_enc/gl2_enc.cpp index fb70443a..814021bb 100644 --- a/system/GLESv2_enc/gl2_enc.cpp +++ b/system/GLESv2_enc/gl2_enc.cpp @@ -3344,7 +3344,7 @@ void glTexImage2D_enc(void *self , GLenum target, GLint level, GLint internalfor stream->writeFully(&__size_pixels,4); if (useChecksum) checksumCalculator->addBuffer(&__size_pixels,4); if (pixels != NULL) { - stream->uploadPixels(self, width, height, format, type, pixels); + stream->uploadPixels(self, width, height, 1, format, type, pixels); if (useChecksum) checksumCalculator->addBuffer(pixels, __size_pixels); } buf = stream->alloc(checksumSize); @@ -3497,7 +3497,7 @@ void glTexSubImage2D_enc(void *self , GLenum target, GLint level, GLint xoffset, stream->writeFully(&__size_pixels,4); if (useChecksum) checksumCalculator->addBuffer(&__size_pixels,4); if (pixels != NULL) { - stream->uploadPixels(self, width, height, format, type, pixels); + stream->uploadPixels(self, width, height, 1, format, type, pixels); if (useChecksum) checksumCalculator->addBuffer(pixels, __size_pixels); } buf = stream->alloc(checksumSize); @@ -8489,7 +8489,7 @@ void glTexImage3D_enc(void *self , GLenum target, GLint level, GLint internalFor stream->writeFully(&__size_data,4); if (useChecksum) checksumCalculator->addBuffer(&__size_data,4); if (data != NULL) { - stream->writeFully(data, __size_data); + stream->uploadPixels(self, width, height, depth, format, type, data); if (useChecksum) checksumCalculator->addBuffer(data, __size_data); } buf = stream->alloc(checksumSize); @@ -8596,7 +8596,7 @@ void glTexSubImage3D_enc(void *self , GLenum target, GLint level, GLint xoffset, stream->writeFully(&__size_data,4); if (useChecksum) checksumCalculator->addBuffer(&__size_data,4); if (data != NULL) { - stream->writeFully(data, __size_data); + stream->uploadPixels(self, width, height, depth, format, type, data); if (useChecksum) checksumCalculator->addBuffer(data, __size_data); } buf = stream->alloc(checksumSize); |