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 int totalReadback = 0;
43
44 if (startOffset > 0) {
45 std::vector<char> paddingToDiscard(startOffset, 0);
46 readback(&paddingToDiscard[0], startOffset);
47 totalReadback += startOffset;
48 }
49 // need to read back row by row
50 size_t paddingSize = totalRowSize - pixelRowSize;
51 std::vector<char> paddingToDiscard(paddingSize, 0);
52
53 char* start = (char*)pixels + startOffset;
54
55 for (int i = 0; i < height; i++) {
56 if (pixelRowSize != width * bpp) {
57 size_t rowSlack = pixelRowSize - width * bpp;
58 std::vector<char> rowSlackToDiscard(rowSlack, 0);
59 readback(start, width * bpp);
60 readback(&rowSlackToDiscard[0], rowSlack);
61 totalReadback += pixelRowSize;
62 readback(&paddingToDiscard[0], paddingSize);
63 totalReadback += paddingSize;
64 start += totalRowSize;
65 } else {
66 readback(start, pixelRowSize);
67 totalReadback += pixelRowSize;
68 readback(&paddingToDiscard[0], paddingSize);
69 totalReadback += paddingSize;
70 start += totalRowSize;
71 }
72 }
73 }
74 }
75
uploadPixels(void * context,int width,int height,int depth,unsigned int format,unsigned int type,const void * pixels)76 void IOStream::uploadPixels(void* context, int width, int height, int depth, unsigned int format, unsigned int type, const void* pixels) {
77 GL2Encoder *ctx = (GL2Encoder *)context;
78 assert (ctx->state() != NULL);
79
80 if (1 == depth) {
81 int bpp = 0;
82 int startOffset = 0;
83 int pixelRowSize = 0;
84 int totalRowSize = 0;
85 int skipRows = 0;
86
87 ctx->state()->getUnpackingOffsets2D(width, height, format, type,
88 &bpp,
89 &startOffset,
90 &pixelRowSize,
91 &totalRowSize,
92 &skipRows);
93
94 size_t pixelDataSize =
95 ctx->state()->pixelDataSize(
96 width, height, 1, format, type, 0 /* is unpack */);
97
98 if (startOffset == 0 &&
99 pixelRowSize == totalRowSize) {
100 // fast path
101 writeFully(pixels, pixelDataSize);
102 } else if (pixelRowSize == totalRowSize && (pixelRowSize == width * bpp)) {
103 // fast path but with skip in the beginning
104 std::vector<char> paddingToDiscard(startOffset, 0);
105 writeFully(&paddingToDiscard[0], startOffset);
106 writeFully((char*)pixels + startOffset, pixelDataSize - startOffset);
107 } else {
108 int totalReadback = 0;
109
110 if (startOffset > 0) {
111 std::vector<char> paddingToDiscard(startOffset, 0);
112 writeFully(&paddingToDiscard[0], startOffset);
113 totalReadback += startOffset;
114 }
115 // need to upload row by row
116 size_t paddingSize = totalRowSize - pixelRowSize;
117 std::vector<char> paddingToDiscard(paddingSize, 0);
118
119 char* start = (char*)pixels + startOffset;
120
121 for (int i = 0; i < height; i++) {
122 if (pixelRowSize != width * bpp) {
123 size_t rowSlack = pixelRowSize - width * bpp;
124 std::vector<char> rowSlackToDiscard(rowSlack, 0);
125 writeFully(start, width * bpp);
126 writeFully(&rowSlackToDiscard[0], rowSlack);
127 totalReadback += pixelRowSize;
128 writeFully(&paddingToDiscard[0], paddingSize);
129 totalReadback += paddingSize;
130 start += totalRowSize;
131 } else {
132 writeFully(start, pixelRowSize);
133 totalReadback += pixelRowSize;
134 writeFully(&paddingToDiscard[0], paddingSize);
135 totalReadback += paddingSize;
136 start += totalRowSize;
137 }
138 }
139 }
140 } else {
141 int bpp = 0;
142 int startOffset = 0;
143 int pixelRowSize = 0;
144 int totalRowSize = 0;
145 int pixelImageSize = 0;
146 int totalImageSize = 0;
147 int skipRows = 0;
148 int skipImages = 0;
149
150 ctx->state()->getUnpackingOffsets3D(width, height, depth, format, type,
151 &bpp,
152 &startOffset,
153 &pixelRowSize,
154 &totalRowSize,
155 &pixelImageSize,
156 &totalImageSize,
157 &skipRows,
158 &skipImages);
159
160 size_t pixelDataSize =
161 ctx->state()->pixelDataSize(
162 width, height, depth, format, type, 0 /* is unpack */);
163
164 size_t sent = 0;
165
166 if (startOffset == 0 &&
167 pixelRowSize == totalRowSize &&
168 pixelImageSize == totalImageSize) {
169 // fast path
170 writeFully(pixels, pixelDataSize);
171 sent += pixelDataSize;
172 } else if (pixelRowSize == totalRowSize &&
173 pixelImageSize == totalImageSize &&
174 pixelRowSize == (width * bpp)) {
175 // fast path but with skip in the beginning
176 std::vector<char> paddingToDiscard(startOffset, 0);
177 writeFully(&paddingToDiscard[0], startOffset);
178 writeFully((char*)pixels + startOffset, pixelDataSize - startOffset);
179 sent += pixelDataSize;
180 } else {
181 int totalReadback = 0;
182
183 if (startOffset > 0) {
184 std::vector<char> paddingToDiscard(startOffset, 0);
185 writeFully(&paddingToDiscard[0], startOffset);
186 totalReadback += startOffset;
187 }
188 // need to upload row by row
189 size_t paddingSize = totalRowSize - pixelRowSize;
190 std::vector<char> paddingToDiscard(paddingSize, 0);
191
192 char* start = (char*)pixels + startOffset;
193
194 size_t rowSlack = pixelRowSize - width * bpp;
195 std::vector<char> rowSlackToDiscard(rowSlack, 0);
196
197 size_t imageSlack = totalImageSize - pixelImageSize;
198 std::vector<char> imageSlackToDiscard(imageSlack, 0);
199
200 for (int k = 0; k < depth; ++k) {
201 for (int i = 0; i < height; i++) {
202 if (pixelRowSize != width * bpp) {
203 writeFully(start, width * bpp);
204 writeFully(&rowSlackToDiscard[0], rowSlack);
205 totalReadback += pixelRowSize;
206 writeFully(&paddingToDiscard[0], paddingSize);
207 totalReadback += paddingSize;
208 start += totalRowSize;
209 } else {
210 writeFully(start, pixelRowSize);
211 totalReadback += pixelRowSize;
212 writeFully(&paddingToDiscard[0], paddingSize);
213 totalReadback += paddingSize;
214 start += totalRowSize;
215 }
216 }
217 if (imageSlack > 0) {
218 writeFully(&imageSlackToDiscard[0], imageSlack);
219 start += imageSlack;
220 totalReadback += imageSlack;
221 }
222 }
223 }
224 }
225 }
226