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