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