/* $Id: server_texture.cpp 78375 2019-05-03 21:51:02Z vboxsync $ */ /** @file * VBox crOpenGL - teximage functions. */ /* * Copyright (C) 2010-2019 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; * you can redistribute it and/or modify it under the terms of the GNU * General Public License (GPL) as published by the Free Software * Foundation, in version 2 as it comes in the "COPYING" file of the * VirtualBox OSE distribution. VirtualBox OSE is distributed in the * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. */ #include "chromium.h" #include "cr_error.h" #include "server_dispatch.h" #include "server.h" #include "cr_mem.h" #define CR_NOTHING() #define CR_CHECKPTR(name) \ if (!realptr) \ { \ crWarning(#name " with NULL ptr, ignored!"); \ return; \ } #if !defined(CR_STATE_NO_TEXTURE_IMAGE_STORE) # define CR_FIXPTR() (uintptr_t) realptr += (uintptr_t) cr_server.head_spu->dispatch_table.MapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_READ_ONLY_ARB) #else # define CR_FIXPTR() #endif #if defined(CR_ARB_pixel_buffer_object) # define CR_CHECKBUFFER(name, checkptr) \ if (crStateIsBufferBound(&cr_server.StateTracker, GL_PIXEL_UNPACK_BUFFER_ARB)) \ { \ CR_FIXPTR(); \ } \ else \ { \ checkptr \ } #else # define CR_CHECKBUFFER(name, checkptr) checkptr #endif #if defined(CR_ARB_pixel_buffer_object) && !defined(CR_STATE_NO_TEXTURE_IMAGE_STORE) # define CR_FINISHBUFFER() \ if (crStateIsBufferBound(&cr_server.StateTracker, GL_PIXEL_UNPACK_BUFFER_ARB)) \ { \ if (!cr_server.head_spu->dispatch_table.UnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB)) \ { \ crWarning("UnmapBufferARB failed"); \ } \ } #else #define CR_FINISHBUFFER() #endif #define CR_FUNC_SUBIMAGE(name, def, state_call, call, ptrname) \ void SERVER_DISPATCH_APIENTRY \ crServerDispatch##name def \ { \ const GLvoid *realptr = ptrname; \ CR_CHECKBUFFER(name, CR_CHECKPTR(name)) \ crState##name state_call; \ CR_FINISHBUFFER() \ realptr = ptrname; \ cr_server.head_spu->dispatch_table.name call; \ } #define CR_FUNC_IMAGE(name, def, state_call, call, ptrname) \ void SERVER_DISPATCH_APIENTRY \ crServerDispatch##name def \ { \ const GLvoid *realptr = ptrname; \ CR_CHECKBUFFER(name, CR_NOTHING()) \ crState##name state_call; \ CR_FINISHBUFFER() \ realptr = ptrname; \ cr_server.head_spu->dispatch_table.name call; \ } #if defined(CR_ARB_texture_compression) CR_FUNC_SUBIMAGE(CompressedTexSubImage1DARB, (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imagesize, const GLvoid * data), (&cr_server.StateTracker, target, level, xoffset, width, format, imagesize, realptr), (target, level, xoffset, width, format, imagesize, realptr), data) CR_FUNC_SUBIMAGE(CompressedTexSubImage2DARB, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imagesize, const GLvoid * data), (&cr_server.StateTracker, target, level, xoffset, yoffset, width, height, format, imagesize, realptr), (target, level, xoffset, yoffset, width, height, format, imagesize, realptr), data) CR_FUNC_SUBIMAGE(CompressedTexSubImage3DARB, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imagesize, const GLvoid * data), (&cr_server.StateTracker, target, level, xoffset, yoffset, zoffset, width, height, depth, format, imagesize, realptr), (target, level, xoffset, yoffset, zoffset, width, height, depth, format, imagesize, realptr), data) CR_FUNC_IMAGE(CompressedTexImage1DARB, (GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLint border, GLsizei imagesize, const GLvoid * data), (&cr_server.StateTracker, target, level, internalFormat, width, border, imagesize, realptr), (target, level, internalFormat, width, border, imagesize, realptr), data) CR_FUNC_IMAGE(CompressedTexImage2DARB, (GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLsizei imagesize, const GLvoid * data), (&cr_server.StateTracker, target, level, internalFormat, width, height, border, imagesize, realptr), (target, level, internalFormat, width, height, border, imagesize, realptr), data) CR_FUNC_IMAGE(CompressedTexImage3DARB, (GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imagesize, const GLvoid * data), (&cr_server.StateTracker, target, level, internalFormat, width, height, depth, border, imagesize, realptr), (target, level, internalFormat, width, height, depth, border, imagesize, realptr), data) #endif CR_FUNC_SUBIMAGE(TexSubImage1D, (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid * pixels), (&cr_server.StateTracker, target, level, xoffset, width, format, type, realptr), (target, level, xoffset, width, format, type, realptr), pixels) CR_FUNC_SUBIMAGE(TexSubImage2D, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * pixels), (&cr_server.StateTracker, target, level, xoffset, yoffset, width, height, format, type, realptr), (target, level, xoffset, yoffset, width, height, format, type, realptr), pixels) CR_FUNC_SUBIMAGE(TexSubImage3D, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid * pixels), (&cr_server.StateTracker, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, realptr), (target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, realptr), pixels) CR_FUNC_IMAGE(TexImage1D, (GLenum target, GLint level, GLint internalFormat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid * pixels), (&cr_server.StateTracker, target, level, internalFormat, width, border, format, type, realptr), (target, level, internalFormat, width, border, format, type, realptr), pixels) CR_FUNC_IMAGE(TexImage2D, (GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid * pixels), (&cr_server.StateTracker, target, level, internalFormat, width, height, border, format, type, realptr), (target, level, internalFormat, width, height, border, format, type, realptr), pixels) CR_FUNC_IMAGE(TexImage3D, (GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid * pixels), (&cr_server.StateTracker, target, level, internalFormat, width, height, depth, border, format, type, realptr), (target, level, internalFormat, width, height, depth, border, format, type, realptr), pixels) void SERVER_DISPATCH_APIENTRY crServerDispatchTexEnvf( GLenum target, GLenum pname, GLfloat param ) { crStateTexEnvf(&cr_server.StateTracker, target, pname, param ); if (GL_POINT_SPRITE != target && pname != GL_COORD_REPLACE) CR_GLERR_CHECK(cr_server.head_spu->dispatch_table.TexEnvf( target, pname, param );); } void SERVER_DISPATCH_APIENTRY crServerDispatchTexEnvfv( GLenum target, GLenum pname, const GLfloat * params ) { crStateTexEnvfv(&cr_server.StateTracker, target, pname, params ); if (GL_POINT_SPRITE != target && pname != GL_COORD_REPLACE) CR_GLERR_CHECK(cr_server.head_spu->dispatch_table.TexEnvfv( target, pname, params );); } void SERVER_DISPATCH_APIENTRY crServerDispatchTexEnvi( GLenum target, GLenum pname, GLint param ) { crStateTexEnvi(&cr_server.StateTracker, target, pname, param ); if (GL_POINT_SPRITE != target && pname != GL_COORD_REPLACE) CR_GLERR_CHECK(cr_server.head_spu->dispatch_table.TexEnvi( target, pname, param );); } void SERVER_DISPATCH_APIENTRY crServerDispatchTexEnviv( GLenum target, GLenum pname, const GLint * params ) { crStateTexEnviv(&cr_server.StateTracker, target, pname, params ); if (GL_POINT_SPRITE != target && pname != GL_COORD_REPLACE) CR_GLERR_CHECK(cr_server.head_spu->dispatch_table.TexEnviv( target, pname, params );); } void SERVER_DISPATCH_APIENTRY crServerDispatchGetTexEnvfv( GLenum target, GLenum pname, GLfloat * params ) { unsigned int cComponents = 0; GLfloat local_params[4] = {0}; (void) params; if (GL_POINT_SPRITE != target && pname != GL_COORD_REPLACE) cr_server.head_spu->dispatch_table.GetTexEnvfv( target, pname, local_params ); else crStateGetTexEnvfv(&cr_server.StateTracker, target, pname, local_params ); cComponents = RT_MIN(crStateHlpComponentsCount(pname), RT_ELEMENTS(local_params)); crServerReturnValue( &(local_params[0]), cComponents*sizeof (GLfloat) ); } void SERVER_DISPATCH_APIENTRY crServerDispatchGetTexEnviv( GLenum target, GLenum pname, GLint * params ) { unsigned int cComponents = 0; GLint local_params[4] = {0}; (void) params; if (GL_POINT_SPRITE != target && pname != GL_COORD_REPLACE) cr_server.head_spu->dispatch_table.GetTexEnviv( target, pname, local_params ); else crStateGetTexEnviv(&cr_server.StateTracker, target, pname, local_params ); cComponents = RT_MIN(crStateHlpComponentsCount(pname), RT_ELEMENTS(local_params)); crServerReturnValue( &(local_params[0]), cComponents*sizeof (GLint) ); } void SERVER_DISPATCH_APIENTRY crServerDispatchBindTexture( GLenum target, GLuint texture ) { crStateBindTexture(&cr_server.StateTracker, target, texture ); cr_server.head_spu->dispatch_table.BindTexture(target, crStateGetTextureHWID(&cr_server.StateTracker, texture)); } void SERVER_DISPATCH_APIENTRY crServerDispatchDeleteTextures( GLsizei n, const GLuint *textures) { GLuint *newTextures; GLint i; if (n <= 0 || n >= INT32_MAX / sizeof(GLuint)) { crError("crServerDispatchDeleteTextures: parameter 'n' is out of range"); return; } newTextures = (GLuint *)crAlloc(n * sizeof(GLuint)); if (!newTextures) { crError("crServerDispatchDeleteTextures: out of memory"); return; } for (i = 0; i < n; i++) { newTextures[i] = crStateGetTextureHWID(&cr_server.StateTracker, textures[i]); } // for (i = 0; i < n; ++i) // { // crDebug("DeleteTexture: %d, pid %d, ctx %d", textures[i], (uint32_t)cr_server.curClient->pid, cr_server.currentCtxInfo->pContext->id); // } crStateDeleteTextures(&cr_server.StateTracker, n, textures); cr_server.head_spu->dispatch_table.DeleteTextures(n, newTextures); crFree(newTextures); } void SERVER_DISPATCH_APIENTRY crServerDispatchPrioritizeTextures( GLsizei n, const GLuint * textures, const GLclampf * priorities ) { GLuint *newTextures; GLint i; if (n <= 0 || n >= INT32_MAX / sizeof(GLuint)) { crError("crServerDispatchPrioritizeTextures: parameter 'n' is out of range"); return; } newTextures = (GLuint *)crAlloc(n * sizeof(GLuint)); if (!newTextures) { crError("crServerDispatchPrioritizeTextures: out of memory"); return; } crStatePrioritizeTextures(&cr_server.StateTracker, n, textures, priorities); for (i = 0; i < n; i++) { newTextures[i] = crStateGetTextureHWID(&cr_server.StateTracker, textures[i]); } cr_server.head_spu->dispatch_table.PrioritizeTextures(n, newTextures, priorities); crFree(newTextures); } /** @todo will fail for textures loaded from snapshot */ GLboolean SERVER_DISPATCH_APIENTRY crServerDispatchIsTexture( GLuint texture ) { GLboolean retval; retval = cr_server.head_spu->dispatch_table.IsTexture(crStateGetTextureHWID(&cr_server.StateTracker, texture)); crServerReturnValue( &retval, sizeof(retval) ); return retval; /* WILL PROBABLY BE IGNORED */ } GLboolean SERVER_DISPATCH_APIENTRY crServerDispatchAreTexturesResident(GLsizei n, const GLuint *textures, GLboolean *residences) { GLboolean retval = GL_FALSE; GLsizei i; GLboolean *res; GLuint *textures2; (void) residences; if (n <= 0 || n >= INT32_MAX / sizeof(GLuint)) { crError("crServerDispatchAreTexturesResident: parameter 'n' is out of range"); return GL_FALSE; } res = (GLboolean *)crCalloc(n * sizeof(GLboolean)); if (!res) { crError("crServerDispatchAreTexturesResident: out of memory"); return GL_FALSE; } textures2 = (GLuint *)crAlloc(n * sizeof(GLuint)); if (!textures2) { crError("crServerDispatchAreTexturesResident: out of memory"); crFree(res); return GL_FALSE; } for (i = 0; i < n; i++) { textures2[i] = crStateGetTextureHWID(&cr_server.StateTracker, textures[i]); } retval = cr_server.head_spu->dispatch_table.AreTexturesResident(n, textures2, res); crFree(textures2); crServerReturnValue(res, n * sizeof(GLboolean)); crFree(res); return retval; /* WILL PROBABLY BE IGNORED */ }