1 | /* Copyright (c) 2001, Stanford University
|
---|
2 | * All rights reserved
|
---|
3 | *
|
---|
4 | * See the file LICENSE.txt for information on redistributing this software.
|
---|
5 | */
|
---|
6 |
|
---|
7 | #include "cr_spu.h"
|
---|
8 | #include "chromium.h"
|
---|
9 | #include "cr_error.h"
|
---|
10 | #include "cr_mem.h"
|
---|
11 | #include "cr_net.h"
|
---|
12 | #include "cr_pixeldata.h"
|
---|
13 | #include "cr_unpack.h"
|
---|
14 | #include "server_dispatch.h"
|
---|
15 | #include "server.h"
|
---|
16 |
|
---|
17 |
|
---|
18 | void SERVER_DISPATCH_APIENTRY
|
---|
19 | crServerDispatchReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
|
---|
20 | GLenum format, GLenum type, GLvoid *pixels)
|
---|
21 | {
|
---|
22 | const GLint stride = READ_DATA( 24, GLint );
|
---|
23 | const GLint alignment = READ_DATA( 28, GLint );
|
---|
24 | const GLint skipRows = READ_DATA( 32, GLint );
|
---|
25 | const GLint skipPixels = READ_DATA( 36, GLint );
|
---|
26 | const GLint bytes_per_row = READ_DATA( 40, GLint );
|
---|
27 | const GLint rowLength = READ_DATA( 44, GLint );
|
---|
28 |
|
---|
29 | CRASSERT(bytes_per_row > 0);
|
---|
30 |
|
---|
31 | #ifdef CR_ARB_pixel_buffer_object
|
---|
32 | if (crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
|
---|
33 | {
|
---|
34 | GLvoid *pbo_offset;
|
---|
35 |
|
---|
36 | /*pixels are actually a pointer to location of 8byte network pointer in hgcm buffer
|
---|
37 | regardless of guest/host bitness we're using only 4lower bytes as there're no
|
---|
38 | pbo>4gb (yet?)
|
---|
39 | */
|
---|
40 | pbo_offset = (GLvoid*) ((uintptr_t) *((GLint*)pixels));
|
---|
41 |
|
---|
42 | cr_server.head_spu->dispatch_table.ReadPixels(x, y, width, height,
|
---|
43 | format, type, pbo_offset);
|
---|
44 | }
|
---|
45 | else
|
---|
46 | #endif
|
---|
47 | {
|
---|
48 | CRMessageReadPixels *rp;
|
---|
49 | uint32_t msg_len;
|
---|
50 |
|
---|
51 | if (bytes_per_row < 0 || bytes_per_row > UINT32_MAX / 8 || height > UINT32_MAX / 8)
|
---|
52 | {
|
---|
53 | crError("crServerDispatchReadPixels: parameters out of range");
|
---|
54 | return;
|
---|
55 | }
|
---|
56 |
|
---|
57 | msg_len = sizeof(*rp) + (uint32_t)bytes_per_row * height;
|
---|
58 |
|
---|
59 | rp = (CRMessageReadPixels *) crAlloc( msg_len );
|
---|
60 | if (!rp)
|
---|
61 | {
|
---|
62 | crError("crServerDispatchReadPixels: out of memory");
|
---|
63 | return;
|
---|
64 | }
|
---|
65 |
|
---|
66 | /* Note: the ReadPixels data gets densely packed into the buffer
|
---|
67 | * (no skip pixels, skip rows, etc. It's up to the receiver (pack spu,
|
---|
68 | * tilesort spu, etc) to apply the real PixelStore packing parameters.
|
---|
69 | */
|
---|
70 | cr_server.head_spu->dispatch_table.ReadPixels(x, y, width, height,
|
---|
71 | format, type, rp + 1);
|
---|
72 |
|
---|
73 | rp->header.type = CR_MESSAGE_READ_PIXELS;
|
---|
74 | rp->width = width;
|
---|
75 | rp->height = height;
|
---|
76 | rp->bytes_per_row = bytes_per_row;
|
---|
77 | rp->stride = stride;
|
---|
78 | rp->format = format;
|
---|
79 | rp->type = type;
|
---|
80 | rp->alignment = alignment;
|
---|
81 | rp->skipRows = skipRows;
|
---|
82 | rp->skipPixels = skipPixels;
|
---|
83 | rp->rowLength = rowLength;
|
---|
84 |
|
---|
85 | /* <pixels> points to the 8-byte network pointer */
|
---|
86 | crMemcpy( &rp->pixels, pixels, sizeof(rp->pixels) );
|
---|
87 |
|
---|
88 | crNetSend( cr_server.curClient->conn, NULL, rp, msg_len );
|
---|
89 | crFree( rp );
|
---|
90 | }
|
---|
91 | }
|
---|