aboutsummaryrefslogtreecommitdiffstats
path: root/system/GLESv2_enc/IOStream2.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'system/GLESv2_enc/IOStream2.cpp')
-rw-r--r--system/GLESv2_enc/IOStream2.cpp113
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;
+ }
+ }
+}