diff options
Diffstat (limited to 'system/GLESv2_enc/IOStream2.cpp')
-rw-r--r-- | system/GLESv2_enc/IOStream2.cpp | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/system/GLESv2_enc/IOStream2.cpp b/system/GLESv2_enc/IOStream2.cpp new file mode 100644 index 00000000..1362d3e1 --- /dev/null +++ b/system/GLESv2_enc/IOStream2.cpp @@ -0,0 +1,113 @@ +#include "IOStream.h" + +#include "GL2Encoder.h" + +#include <GLES3/gl31.h> + +#include <vector> + +#include <assert.h> + +void IOStream::readbackPixels(void* context, int width, int height, unsigned int format, unsigned int type, void* pixels) { + GL2Encoder *ctx = (GL2Encoder *)context; + assert (ctx->state() != NULL); + + int startOffset = 0; + int pixelRowSize = 0; + int totalRowSize = 0; + int skipRows = 0; + + ctx->state()->getPackingOffsets2D(width, height, format, type, + &startOffset, + &pixelRowSize, + &totalRowSize, + &skipRows); + + size_t pixelDataSize = + ctx->state()->pixelDataSize( + width, height, 1, format, type, 1 /* is pack */); + + if (startOffset == 0 && + pixelRowSize == totalRowSize) { + // fast path + readback(pixels, pixelDataSize); + } else if (pixelRowSize == totalRowSize) { + // fast path but with skip in the beginning + std::vector<char> paddingToDiscard(startOffset, 0); + readback(&paddingToDiscard[0], startOffset); + readback((char*)pixels + startOffset, pixelDataSize - startOffset); + } else { + int totalReadback = 0; + + if (startOffset > 0) { + std::vector<char> paddingToDiscard(startOffset, 0); + readback(&paddingToDiscard[0], startOffset); + totalReadback += startOffset; + } + // need to read back 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++) { + 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) { + 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) { + 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++) { + writeFully(start, pixelRowSize); + totalReadback += pixelRowSize; + writeFully(&paddingToDiscard[0], paddingSize); + totalReadback += paddingSize; + start += totalRowSize; + } + } +} |