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 | CRASSERT(cr_server.pUnpackerState != NULL);
|
---|
23 | CHECK_BUFFER_SIZE_STATIC(cr_server.pUnpackerState, 44 + sizeof(GLint));
|
---|
24 |
|
---|
25 | const GLint stride = READ_DATA(cr_server.pUnpackerState, 24, GLint );
|
---|
26 | const GLint alignment = READ_DATA(cr_server.pUnpackerState, 28, GLint );
|
---|
27 | const GLint skipRows = READ_DATA(cr_server.pUnpackerState, 32, GLint );
|
---|
28 | const GLint skipPixels = READ_DATA(cr_server.pUnpackerState, 36, GLint );
|
---|
29 | const GLint bytes_per_row = READ_DATA(cr_server.pUnpackerState, 40, GLint );
|
---|
30 | const GLint rowLength = READ_DATA(cr_server.pUnpackerState, 44, GLint );
|
---|
31 |
|
---|
32 | CRASSERT(bytes_per_row > 0);
|
---|
33 |
|
---|
34 | #ifdef CR_ARB_pixel_buffer_object
|
---|
35 | if (crStateIsBufferBound(&cr_server.StateTracker, GL_PIXEL_PACK_BUFFER_ARB))
|
---|
36 | {
|
---|
37 | GLvoid *pbo_offset;
|
---|
38 |
|
---|
39 | /*pixels are actually a pointer to location of 8byte network pointer in hgcm buffer
|
---|
40 | regardless of guest/host bitness we're using only 4lower bytes as there're no
|
---|
41 | pbo>4gb (yet?)
|
---|
42 | */
|
---|
43 | pbo_offset = (GLvoid*) ((uintptr_t) *((GLint*)pixels));
|
---|
44 |
|
---|
45 | cr_server.head_spu->dispatch_table.ReadPixels(x, y, width, height,
|
---|
46 | format, type, pbo_offset);
|
---|
47 | }
|
---|
48 | else
|
---|
49 | #endif
|
---|
50 | {
|
---|
51 | CRMessageReadPixels *rp;
|
---|
52 | uint32_t msg_len;
|
---|
53 |
|
---|
54 | if (bytes_per_row <= 0 || height <= 0 || bytes_per_row > INT32_MAX / height)
|
---|
55 | {
|
---|
56 | crError("crServerDispatchReadPixels: parameters out of range");
|
---|
57 | return;
|
---|
58 | }
|
---|
59 |
|
---|
60 | msg_len = sizeof(*rp) + (uint32_t)bytes_per_row * height;
|
---|
61 |
|
---|
62 | rp = (CRMessageReadPixels *) crAlloc( msg_len );
|
---|
63 | if (!rp)
|
---|
64 | {
|
---|
65 | crError("crServerDispatchReadPixels: out of memory");
|
---|
66 | return;
|
---|
67 | }
|
---|
68 |
|
---|
69 | /* Note: the ReadPixels data gets densely packed into the buffer
|
---|
70 | * (no skip pixels, skip rows, etc. It's up to the receiver (pack spu,
|
---|
71 | * tilesort spu, etc) to apply the real PixelStore packing parameters.
|
---|
72 | */
|
---|
73 | cr_server.head_spu->dispatch_table.ReadPixels(x, y, width, height,
|
---|
74 | format, type, rp + 1);
|
---|
75 |
|
---|
76 | rp->header.type = CR_MESSAGE_READ_PIXELS;
|
---|
77 | rp->width = width;
|
---|
78 | rp->height = height;
|
---|
79 | rp->bytes_per_row = bytes_per_row;
|
---|
80 | rp->stride = stride;
|
---|
81 | rp->format = format;
|
---|
82 | rp->type = type;
|
---|
83 | rp->alignment = alignment;
|
---|
84 | rp->skipRows = skipRows;
|
---|
85 | rp->skipPixels = skipPixels;
|
---|
86 | rp->rowLength = rowLength;
|
---|
87 |
|
---|
88 | /* <pixels> points to the 8-byte network pointer */
|
---|
89 | crMemcpy( &rp->pixels, pixels, sizeof(rp->pixels) );
|
---|
90 |
|
---|
91 | crNetSend( cr_server.curClient->conn, NULL, rp, msg_len );
|
---|
92 | crFree( rp );
|
---|
93 | }
|
---|
94 | }
|
---|