server_misc.c revision 88c504b1c053e580e42d5fc90ef2ccedc50c65bd
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/* Copyright (c) 2001, Stanford University
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * All rights reserved
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync *
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * See the file LICENSE.txt for information on redistributing this software.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include "server_dispatch.h"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include "server.h"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include "cr_error.h"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include "cr_mem.h"
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync#include "cr_string.h"
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync#include "cr_pixeldata.h"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid SERVER_DISPATCH_APIENTRY crServerDispatchSelectBuffer( GLsizei size, GLuint *buffer )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync (void) size;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync (void) buffer;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crError( "Unsupported network glSelectBuffer call." );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid SERVER_DISPATCH_APIENTRY crServerDispatchGetChromiumParametervCR(GLenum target, GLuint index, GLenum type, GLsizei count, GLvoid *values)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync GLubyte local_storage[4096];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync GLint bytes = 0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync switch (type) {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync case GL_BYTE:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync case GL_UNSIGNED_BYTE:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync bytes = count * sizeof(GLbyte);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync case GL_SHORT:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync case GL_UNSIGNED_SHORT:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync bytes = count * sizeof(GLshort);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync case GL_INT:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync case GL_UNSIGNED_INT:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync bytes = count * sizeof(GLint);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync case GL_FLOAT:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync bytes = count * sizeof(GLfloat);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync case GL_DOUBLE:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync bytes = count * sizeof(GLdouble);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync default:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crError("Bad type in crServerDispatchGetChromiumParametervCR");
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRASSERT(bytes >= 0);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRASSERT(bytes < 4096);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.head_spu->dispatch_table.GetChromiumParametervCR( target, index, type, count, local_storage );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crServerReturnValue( local_storage, bytes );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid SERVER_DISPATCH_APIENTRY crServerDispatchChromiumParametervCR(GLenum target, GLenum type, GLsizei count, const GLvoid *values)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRMuralInfo *mural = cr_server.curClient->currentMural;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync static int gather_connect_count = 0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync switch (target) {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync case GL_SET_MAX_VIEWPORT_CR:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync GLint *maxDims = (GLint *)values;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.limits.maxViewportDims[0] = maxDims[0];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.limits.maxViewportDims[1] = maxDims[1];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync case GL_TILE_INFO_CR:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* message from tilesort SPU to set new tile bounds */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync GLint numTiles, muralWidth, muralHeight, server, tiles;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync GLint *tileBounds;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRASSERT(count >= 4);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRASSERT((count - 4) % 4 == 0); /* must be multiple of four */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRASSERT(type == GL_INT);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync numTiles = (count - 4) / 4;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync tileBounds = (GLint *) values;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync server = tileBounds[0];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync muralWidth = tileBounds[1];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync muralHeight = tileBounds[2];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync tiles = tileBounds[3];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRASSERT(tiles == numTiles);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync tileBounds += 4; /* skip over header values */
81b3101ea5e60964f67c97185bbd43dbf75c5ab5vboxsync /*crServerNewMuralTiling(mural, muralWidth, muralHeight, numTiles, tileBounds);
81b3101ea5e60964f67c97185bbd43dbf75c5ab5vboxsync mural->viewportValidated = GL_FALSE;*/
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync case GL_GATHER_DRAWPIXELS_CR:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (cr_server.only_swap_once && cr_server.curClient != cr_server.clients[0])
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.head_spu->dispatch_table.ChromiumParametervCR( target, type, count, values );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync case GL_GATHER_CONNECT_CR:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /*
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * We want the last connect to go through,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * otherwise we might deadlock in CheckWindowSize()
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * in the readback spu
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync gather_connect_count++;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (cr_server.only_swap_once && (gather_connect_count != cr_server.numClients))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.head_spu->dispatch_table.ChromiumParametervCR( target, type, count, values );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync gather_connect_count = 0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync case GL_SERVER_VIEW_MATRIX_CR:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* Set this server's view matrix which will get premultiplied onto the
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * modelview matrix. For non-planar tilesort and stereo.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRASSERT(count == 18);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRASSERT(type == GL_FLOAT);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* values[0] is the server index. Ignored here but used in tilesort SPU */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* values[1] is the left/right eye index (0 or 1) */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const GLfloat *v = (const GLfloat *) values;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const int eye = v[1] == 0.0 ? 0 : 1;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crMatrixInitFromFloats(&cr_server.viewMatrix[eye], v + 2);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crDebug("Got GL_SERVER_VIEW_MATRIX_CR:\n"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync " %f %f %f %f\n"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync " %f %f %f %f\n"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync " %f %f %f %f\n"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync " %f %f %f %f",
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.viewMatrix[eye].m00,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.viewMatrix[eye].m10,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.viewMatrix[eye].m20,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.viewMatrix[eye].m30,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.viewMatrix[eye].m01,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.viewMatrix[eye].m11,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.viewMatrix[eye].m21,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.viewMatrix[eye].m31,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.viewMatrix[eye].m02,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.viewMatrix[eye].m12,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.viewMatrix[eye].m22,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.viewMatrix[eye].m32,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.viewMatrix[eye].m03,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.viewMatrix[eye].m13,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.viewMatrix[eye].m23,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.viewMatrix[eye].m33);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.viewOverride = GL_TRUE;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync case GL_SERVER_PROJECTION_MATRIX_CR:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* Set this server's projection matrix which will get replace the user's
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * projection matrix. For non-planar tilesort and stereo.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRASSERT(count == 18);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRASSERT(type == GL_FLOAT);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* values[0] is the server index. Ignored here but used in tilesort SPU */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* values[1] is the left/right eye index (0 or 1) */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const GLfloat *v = (const GLfloat *) values;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const int eye = v[1] == 0.0 ? 0 : 1;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crMatrixInitFromFloats(&cr_server.projectionMatrix[eye], v + 2);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crDebug("Got GL_SERVER_PROJECTION_MATRIX_CR:\n"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync " %f %f %f %f\n"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync " %f %f %f %f\n"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync " %f %f %f %f\n"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync " %f %f %f %f",
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.projectionMatrix[eye].m00,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.projectionMatrix[eye].m10,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.projectionMatrix[eye].m20,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.projectionMatrix[eye].m30,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.projectionMatrix[eye].m01,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.projectionMatrix[eye].m11,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.projectionMatrix[eye].m21,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.projectionMatrix[eye].m31,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.projectionMatrix[eye].m02,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.projectionMatrix[eye].m12,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.projectionMatrix[eye].m22,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.projectionMatrix[eye].m32,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.projectionMatrix[eye].m03,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.projectionMatrix[eye].m13,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.projectionMatrix[eye].m23,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.projectionMatrix[eye].m33);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (cr_server.projectionMatrix[eye].m33 == 0.0f) {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync float x = cr_server.projectionMatrix[eye].m00;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync float y = cr_server.projectionMatrix[eye].m11;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync float a = cr_server.projectionMatrix[eye].m20;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync float b = cr_server.projectionMatrix[eye].m21;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync float c = cr_server.projectionMatrix[eye].m22;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync float d = cr_server.projectionMatrix[eye].m32;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync float znear = -d / (1.0f - c);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync float zfar = (c - 1.0f) * znear / (c + 1.0f);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync float left = znear * (a - 1.0f) / x;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync float right = 2.0f * znear / x + left;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync float bottom = znear * (b - 1.0f) / y;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync float top = 2.0f * znear / y + bottom;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crDebug("Frustum: left, right, bottom, top, near, far: %f, %f, %f, %f, %f, %f", left, right, bottom, top, znear, zfar);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync else {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* Todo: Add debug output for orthographic projection*/
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.projectionOverride = GL_TRUE;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync default:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* Pass the parameter info to the head SPU */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.head_spu->dispatch_table.ChromiumParametervCR( target, type, count, values );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid SERVER_DISPATCH_APIENTRY crServerDispatchChromiumParameteriCR(GLenum target, GLint value)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync switch (target) {
c62d2520ac91e12cf4665c936f490dd2064152d3vboxsync case GL_SHARE_CONTEXT_RESOURCES_CR:
c62d2520ac91e12cf4665c936f490dd2064152d3vboxsync crStateShareContext(value);
c62d2520ac91e12cf4665c936f490dd2064152d3vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync case GL_SHARED_DISPLAY_LISTS_CR:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.sharedDisplayLists = value;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync case GL_SHARED_TEXTURE_OBJECTS_CR:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.sharedTextureObjects = value;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync case GL_SHARED_PROGRAMS_CR:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.sharedPrograms = value;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync case GL_SERVER_CURRENT_EYE_CR:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.currentEye = value ? 1 : 0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync default:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* Pass the parameter info to the head SPU */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.head_spu->dispatch_table.ChromiumParameteriCR( target, value );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid SERVER_DISPATCH_APIENTRY crServerDispatchChromiumParameterfCR(GLenum target, GLfloat value)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync switch (target) {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync case GL_SHARED_DISPLAY_LISTS_CR:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.sharedDisplayLists = (int) value;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync case GL_SHARED_TEXTURE_OBJECTS_CR:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.sharedTextureObjects = (int) value;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync case GL_SHARED_PROGRAMS_CR:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.sharedPrograms = (int) value;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync default:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* Pass the parameter info to the head SPU */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.head_spu->dispatch_table.ChromiumParameterfCR( target, value );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid crServerCreateInfoDeleteCB(void *data)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRCreateInfo_t *pCreateInfo = (CRCreateInfo_t *) data;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (pCreateInfo->pszDpyName)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crFree(pCreateInfo->pszDpyName);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncGLint crServerGenerateID(GLint *pCounter)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return (*pCounter)++;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsyncvoid SERVER_DISPATCH_APIENTRY
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsynccrServerDispatchCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync{
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync /*@todo pbo/fbo disabled for now as it's slower, check on other gpus*/
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync static int siHavePBO = 0;
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync static int siHaveFBO = 0;
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync if ((target!=GL_TEXTURE_2D) || (height>=0))
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync {
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync cr_server.head_spu->dispatch_table.CopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync }
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync else /* negative height, means we have to Yinvert the source pixels while copying */
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync {
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync SPUDispatchTable *gl = &cr_server.head_spu->dispatch_table;
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync if (siHavePBO<0)
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync {
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync const char *ext = gl->GetString(GL_EXTENSIONS);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync siHavePBO = crStrstr(ext, "GL_ARB_pixel_buffer_object") ? 1:0;
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync }
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync if (siHaveFBO<0)
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync {
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync const char *ext = gl->GetString(GL_EXTENSIONS);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync siHaveFBO = crStrstr(ext, "GL_EXT_framebuffer_object") ? 1:0;
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync }
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync if (siHavePBO==0 && siHaveFBO==0)
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync {
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync GLint dRow, sRow;
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync for (dRow=yoffset, sRow=y-height-1; dRow<yoffset-height; dRow++, sRow--)
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync {
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->CopyTexSubImage2D(target, level, xoffset, dRow, x, sRow, width, 1);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync }
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync }
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync else if (siHaveFBO==1) /*@todo more states to set and restore here*/
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync {
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync GLint tID, fboID;
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync GLenum status;
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync CRContext *ctx = crStateGetCurrent();
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->GenTextures(1, &tID);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->BindTexture(target, tID);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->CopyTexImage2D(target, level, GL_RGBA, x, y, width, -height, 0);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->GenFramebuffersEXT(1, &fboID);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->BindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboID);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->FramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, target,
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync ctx->texture.unit[ctx->texture.curTextureUnit].currentTexture2D->hwid, level);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync status = gl->CheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync {
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync crWarning("Framebuffer status 0x%x", status);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync }
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->Enable(target);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->PushAttrib(GL_VIEWPORT_BIT);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->Viewport(xoffset, yoffset, width, -height);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->MatrixMode(GL_PROJECTION);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->PushMatrix();
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->LoadIdentity();
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->MatrixMode(GL_MODELVIEW);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->PushMatrix();
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->LoadIdentity();
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->Disable(GL_DEPTH_TEST);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->Disable(GL_CULL_FACE);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->Disable(GL_STENCIL_TEST);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->Disable(GL_SCISSOR_TEST);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->Begin(GL_QUADS);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->TexCoord2f(0.0f, 1.0f);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->Vertex2f(-1.0, -1.0);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->TexCoord2f(0.0f, 0.0f);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->Vertex2f(-1.0f, 1.0f);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->TexCoord2f(1.0f, 0.0f);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->Vertex2f(1.0f, 1.0f);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->TexCoord2f(1.0f, 1.0f);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->Vertex2f(1.0f, -1.0f);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->End();
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->PopMatrix();
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->MatrixMode(GL_PROJECTION);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->PopMatrix();
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->PopAttrib();
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->FramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, target, 0, level);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->BindFramebufferEXT(GL_FRAMEBUFFER_EXT, ctx->framebufferobject.drawFB ? ctx->framebufferobject.drawFB->hwid:0);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->BindTexture(target, ctx->texture.unit[ctx->texture.curTextureUnit].currentTexture2D->hwid);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->DeleteFramebuffersEXT(1, &fboID);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->DeleteTextures(1, &tID);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync#if 0
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync {
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync GLint dRow, sRow, w, h;
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync void *img1, *img2;
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync w = ctx->texture.unit[ctx->texture.curTextureUnit].currentTexture2D->level[0][level].width;
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync h = ctx->texture.unit[ctx->texture.curTextureUnit].currentTexture2D->level[0][level].height;
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync img1 = crAlloc(4*w*h);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync img2 = crAlloc(4*w*h);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync CRASSERT(img1 && img2);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->GetTexImage(target, level, GL_BGRA, GL_UNSIGNED_BYTE, img1);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync for (dRow=yoffset, sRow=y-height-1; dRow<yoffset-height; dRow++, sRow--)
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync {
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->CopyTexSubImage2D(target, level, xoffset, dRow, x, sRow, width, 1);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync }
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->GetTexImage(target, level, GL_BGRA, GL_UNSIGNED_BYTE, img2);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync if (crMemcmp(img1, img2, 4*w*h))
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync {
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync crDebug("MISMATCH! (%x, %i, ->%i,%i <-%i, %i [%ix%i])", target, level, xoffset, yoffset, x, y, width, height);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync crDumpTGA(w, h, img1);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync crDumpTGA(w, h, img2);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync DebugBreak();
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync }
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync crFree(img1);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync crFree(img2);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync }
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync#endif
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync }
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync else
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync {
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync GLint pboId, dRow, sRow;
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync CRContext *ctx = crStateGetCurrent();
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->GenBuffersARB(1, &pboId);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboId);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->BufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, -width*height*4, 0, GL_STATIC_COPY_ARB);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync#if 1
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->ReadPixels(x, y, width, -height, GL_RGBA, GL_UNSIGNED_BYTE, 0);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, ctx->bufferobject.packBuffer->hwid);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pboId);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync for (dRow=yoffset, sRow=-height-1; dRow<yoffset-height; dRow++, sRow--)
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync {
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->TexSubImage2D(target, level, xoffset, dRow, width, 1, GL_RGBA, GL_UNSIGNED_BYTE, (void*)((uintptr_t)sRow*width*4));
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync }
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync#else /*few times slower again*/
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync for (dRow=0, sRow=y-height-1; dRow<-height; dRow++, sRow--)
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync {
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->ReadPixels(x, sRow, width, 1, GL_RGBA, GL_UNSIGNED_BYTE, (void*)((uintptr_t)dRow*width*4));
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync }
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, ctx->bufferobject.packBuffer->hwid);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pboId);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->TexSubImage2D(target, level, xoffset, yoffset, width, -height, GL_RGBA, GL_UNSIGNED_BYTE, 0);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync#endif
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, ctx->bufferobject.unpackBuffer->hwid);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync gl->DeleteBuffersARB(1, &pboId);
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync }
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync }
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync}