1 #include "IOStream.h"
2
3 #include "GL2Encoder.h"
4
5 #include <GLES3/gl31.h>
6
7 #include <vector>
8
9 #include <assert.h>
10
readbackPixels(void * context,int width,int height,unsigned int format,unsigned int type,void * pixels)11 void IOStream::readbackPixels(void* context, int width, int height, unsigned int format, unsigned int type, void* pixels) {
12 GL2Encoder *ctx = (GL2Encoder *)context;
13 assert (ctx->state() != NULL);
14
15 int bpp = 0;
16 int startOffset = 0;
17 int pixelRowSize = 0;
18 int totalRowSize = 0;
19 int skipRows = 0;
20
21 ctx->state()->getPackingOffsets2D(width, height, format, type,
22 &bpp,
23 &startOffset,
24 &pixelRowSize,
25 &totalRowSize,
26 &skipRows);
27
28 size_t pixelDataSize =
29 ctx->state()->pixelDataSize(
30 width, height, 1, format, type, 1 /* is pack */);
31
32 if (startOffset == 0 &&
33 pixelRowSize == totalRowSize) {
34 // fast path
35 readback(pixels, pixelDataSize);
36 } else if (pixelRowSize == totalRowSize && (pixelRowSize == width * bpp)) {
37 // fast path but with skip in the beginning
38 std::vector<char> paddingToDiscard(startOffset, 0);
39 readback(&paddingToDiscard[0], startOffset);
40 readback((char*)pixels + startOffset, pixelDataSize - startOffset);
41 } else {
42
43 if (startOffset > 0) {
44 std::vector<char> paddingToDiscard(startOffset, 0);
45 readback(&paddingToDiscard[0], startOffset);
46 }
47 // need to read back row by row
48 size_t paddingSize = totalRowSize - pixelRowSize;
49 std::vector<char> paddingToDiscard(paddingSize, 0);
50
51 char* start = (char*)pixels + startOffset;
52
53 for (int i = 0; i < height; i++) {
54 if (pixelRowSize > width * bpp) {
55 size_t rowSlack = pixelRowSize - width * bpp;
56 std::vector<char> rowSlackToDiscard(rowSlack, 0);
57 readback(start, width * bpp);
58 readback(&rowSlackToDiscard[0], rowSlack);
59 readback(&paddingToDiscard[0], paddingSize);
60 start += totalRowSize;
61 } else {
62 readback(start, pixelRowSize);
63 readback(&paddingToDiscard[0], paddingSize);
64 start += totalRowSize;
65 }
66 }
67 }
68 }
69
uploadPixels(void * context,int width,int height,int depth,unsigned int format,unsigned int type,const void * pixels)70 void IOStream::uploadPixels(void* context, int width, int height, int depth, unsigned int format, unsigned int type, const void* pixels) {
71 GL2Encoder *ctx = (GL2Encoder *)context;
72 assert (ctx->state() != NULL);
73
74 if (1 == depth) {
75 int bpp = 0;
76 int startOffset = 0;
77 int pixelRowSize = 0;
78 int totalRowSize = 0;
79 int skipRows = 0;
80
81 ctx->state()->getUnpackingOffsets2D(width, height, format, type,
82 &bpp,
83 &startOffset,
84 &pixelRowSize,
85 &totalRowSize,
86 &skipRows);
87
88 size_t pixelDataSize =
89 ctx->state()->pixelDataSize(
90 width, height, 1, format, type, 0 /* is unpack */);
91
92 if (startOffset == 0 &&
93 pixelRowSize == totalRowSize) {
94 // fast path
95 writeFully(pixels, pixelDataSize);
96 } else if (pixelRowSize == totalRowSize && (pixelRowSize == width * bpp)) {
97 // fast path but with skip in the beginning
98 std::vector<char> paddingToDiscard(startOffset, 0);
99 writeFully(&paddingToDiscard[0], startOffset);
100 writeFully((char*)pixels + startOffset, pixelDataSize - startOffset);
101 } else {
102
103 if (startOffset > 0) {
104 std::vector<char> paddingToDiscard(startOffset, 0);
105 writeFully(&paddingToDiscard[0], startOffset);
106 }
107 // need to upload row by row
108 size_t paddingSize = totalRowSize - pixelRowSize;
109 std::vector<char> paddingToDiscard(paddingSize, 0);
110
111 char* start = (char*)pixels + startOffset;
112
113 for (int i = 0; i < height; i++) {
114 if (pixelRowSize > width * bpp) {
115 size_t rowSlack = pixelRowSize - width * bpp;
116 std::vector<char> rowSlackToDiscard(rowSlack, 0);
117 writeFully(start, width * bpp);
118 writeFully(&rowSlackToDiscard[0], rowSlack);
119 writeFully(&paddingToDiscard[0], paddingSize);
120 start += totalRowSize;
121 } else {
122 writeFully(start, pixelRowSize);
123 writeFully(&paddingToDiscard[0], paddingSize);
124 start += totalRowSize;
125 }
126 }
127 }
128 } else {
129 int bpp = 0;
130 int startOffset = 0;
131 int pixelRowSize = 0;
132 int totalRowSize = 0;
133 int pixelImageSize = 0;
134 int totalImageSize = 0;
135 int skipRows = 0;
136 int skipImages = 0;
137
138 ctx->state()->getUnpackingOffsets3D(width, height, depth, format, type,
139 &bpp,
140 &startOffset,
141 &pixelRowSize,
142 &totalRowSize,
143 &pixelImageSize,
144 &totalImageSize,
145 &skipRows,
146 &skipImages);
147
148 size_t pixelDataSize =
149 ctx->state()->pixelDataSize(
150 width, height, depth, format, type, 0 /* is unpack */);
151
152
153 if (startOffset == 0 &&
154 pixelRowSize == totalRowSize &&
155 pixelImageSize == totalImageSize) {
156 // fast path
157 writeFully(pixels, pixelDataSize);
158 } else if (pixelRowSize == totalRowSize &&
159 pixelImageSize == totalImageSize &&
160 pixelRowSize == (width * bpp)) {
161 // fast path but with skip in the beginning
162 std::vector<char> paddingToDiscard(startOffset, 0);
163 writeFully(&paddingToDiscard[0], startOffset);
164 writeFully((char*)pixels + startOffset, pixelDataSize - startOffset);
165 } else {
166
167 if (startOffset > 0) {
168 std::vector<char> paddingToDiscard(startOffset, 0);
169 writeFully(&paddingToDiscard[0], startOffset);
170 }
171 // need to upload row by row
172 size_t paddingSize = totalRowSize - pixelRowSize;
173 std::vector<char> paddingToDiscard(paddingSize, 0);
174
175 char* start = (char*)pixels + startOffset;
176
177 size_t imageSlack = totalImageSize - pixelImageSize;
178 std::vector<char> imageSlackToDiscard(imageSlack, 0);
179
180 for (int k = 0; k < depth; ++k) {
181 for (int i = 0; i < height; i++) {
182 if (pixelRowSize > width * bpp) {
183 size_t rowSlack = pixelRowSize - width * bpp;
184 std::vector<char> rowSlackToDiscard(rowSlack, 0);
185 writeFully(start, width * bpp);
186 writeFully(&rowSlackToDiscard[0], rowSlack);
187 writeFully(&paddingToDiscard[0], paddingSize);
188 start += totalRowSize;
189 } else {
190 writeFully(start, pixelRowSize);
191 writeFully(&paddingToDiscard[0], paddingSize);
192 start += totalRowSize;
193 }
194 }
195 if (imageSlack > 0) {
196 writeFully(&imageSlackToDiscard[0], imageSlack);
197 start += imageSlack;
198 }
199 }
200 }
201 }
202 }
203