• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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