1b8e80941Smrg/* 2b8e80941Smrg * Mesa 3-D graphics library 3b8e80941Smrg * 4b8e80941Smrg * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 5b8e80941Smrg * Copyright (C) 2009 VMware, Inc. All Rights Reserved. 6b8e80941Smrg * 7b8e80941Smrg * Permission is hereby granted, free of charge, to any person obtaining a 8b8e80941Smrg * copy of this software and associated documentation files (the "Software"), 9b8e80941Smrg * to deal in the Software without restriction, including without limitation 10b8e80941Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11b8e80941Smrg * and/or sell copies of the Software, and to permit persons to whom the 12b8e80941Smrg * Software is furnished to do so, subject to the following conditions: 13b8e80941Smrg * 14b8e80941Smrg * The above copyright notice and this permission notice shall be included 15b8e80941Smrg * in all copies or substantial portions of the Software. 16b8e80941Smrg * 17b8e80941Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18b8e80941Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19b8e80941Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20b8e80941Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21b8e80941Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22b8e80941Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23b8e80941Smrg * OTHER DEALINGS IN THE SOFTWARE. 24b8e80941Smrg */ 25b8e80941Smrg 26b8e80941Smrg/** 27b8e80941Smrg * Code related to the GL_APPLE_object_purgeable extension. 28b8e80941Smrg */ 29b8e80941Smrg 30b8e80941Smrg 31b8e80941Smrg#include "glheader.h" 32b8e80941Smrg#include "enums.h" 33b8e80941Smrg#include "hash.h" 34b8e80941Smrg#include "imports.h" 35b8e80941Smrg#include "context.h" 36b8e80941Smrg#include "bufferobj.h" 37b8e80941Smrg#include "fbobject.h" 38b8e80941Smrg#include "mtypes.h" 39b8e80941Smrg#include "objectpurge.h" 40b8e80941Smrg#include "texobj.h" 41b8e80941Smrg#include "teximage.h" 42b8e80941Smrg 43b8e80941Smrg 44b8e80941Smrgstatic GLenum 45b8e80941Smrgbuffer_object_purgeable(struct gl_context *ctx, GLuint name, GLenum option) 46b8e80941Smrg{ 47b8e80941Smrg struct gl_buffer_object *bufObj; 48b8e80941Smrg GLenum retval; 49b8e80941Smrg 50b8e80941Smrg bufObj = _mesa_lookup_bufferobj(ctx, name); 51b8e80941Smrg if (!bufObj) { 52b8e80941Smrg _mesa_error(ctx, GL_INVALID_VALUE, 53b8e80941Smrg "glObjectPurgeable(name = 0x%x)", name); 54b8e80941Smrg return 0; 55b8e80941Smrg } 56b8e80941Smrg if (!_mesa_is_bufferobj(bufObj)) { 57b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "glObjectPurgeable(buffer 0)" ); 58b8e80941Smrg return 0; 59b8e80941Smrg } 60b8e80941Smrg 61b8e80941Smrg if (bufObj->Purgeable) { 62b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 63b8e80941Smrg "glObjectPurgeable(name = 0x%x) is already purgeable", name); 64b8e80941Smrg return GL_VOLATILE_APPLE; 65b8e80941Smrg } 66b8e80941Smrg 67b8e80941Smrg bufObj->Purgeable = GL_TRUE; 68b8e80941Smrg 69b8e80941Smrg retval = GL_VOLATILE_APPLE; 70b8e80941Smrg if (ctx->Driver.BufferObjectPurgeable) 71b8e80941Smrg retval = ctx->Driver.BufferObjectPurgeable(ctx, bufObj, option); 72b8e80941Smrg 73b8e80941Smrg return retval; 74b8e80941Smrg} 75b8e80941Smrg 76b8e80941Smrg 77b8e80941Smrgstatic GLenum 78b8e80941Smrgrenderbuffer_purgeable(struct gl_context *ctx, GLuint name, GLenum option) 79b8e80941Smrg{ 80b8e80941Smrg struct gl_renderbuffer *bufObj; 81b8e80941Smrg GLenum retval; 82b8e80941Smrg 83b8e80941Smrg bufObj = _mesa_lookup_renderbuffer(ctx, name); 84b8e80941Smrg if (!bufObj) { 85b8e80941Smrg _mesa_error(ctx, GL_INVALID_VALUE, 86b8e80941Smrg "glObjectUnpurgeable(name = 0x%x)", name); 87b8e80941Smrg return 0; 88b8e80941Smrg } 89b8e80941Smrg 90b8e80941Smrg if (bufObj->Purgeable) { 91b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 92b8e80941Smrg "glObjectPurgeable(name = 0x%x) is already purgeable", name); 93b8e80941Smrg return GL_VOLATILE_APPLE; 94b8e80941Smrg } 95b8e80941Smrg 96b8e80941Smrg bufObj->Purgeable = GL_TRUE; 97b8e80941Smrg 98b8e80941Smrg retval = GL_VOLATILE_APPLE; 99b8e80941Smrg if (ctx->Driver.RenderObjectPurgeable) 100b8e80941Smrg retval = ctx->Driver.RenderObjectPurgeable(ctx, bufObj, option); 101b8e80941Smrg 102b8e80941Smrg return retval; 103b8e80941Smrg} 104b8e80941Smrg 105b8e80941Smrg 106b8e80941Smrgstatic GLenum 107b8e80941Smrgtexture_object_purgeable(struct gl_context *ctx, GLuint name, GLenum option) 108b8e80941Smrg{ 109b8e80941Smrg struct gl_texture_object *bufObj; 110b8e80941Smrg GLenum retval; 111b8e80941Smrg 112b8e80941Smrg bufObj = _mesa_lookup_texture(ctx, name); 113b8e80941Smrg if (!bufObj) { 114b8e80941Smrg _mesa_error(ctx, GL_INVALID_VALUE, 115b8e80941Smrg "glObjectPurgeable(name = 0x%x)", name); 116b8e80941Smrg return 0; 117b8e80941Smrg } 118b8e80941Smrg 119b8e80941Smrg if (bufObj->Purgeable) { 120b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 121b8e80941Smrg "glObjectPurgeable(name = 0x%x) is already purgeable", name); 122b8e80941Smrg return GL_VOLATILE_APPLE; 123b8e80941Smrg } 124b8e80941Smrg 125b8e80941Smrg bufObj->Purgeable = GL_TRUE; 126b8e80941Smrg 127b8e80941Smrg retval = GL_VOLATILE_APPLE; 128b8e80941Smrg if (ctx->Driver.TextureObjectPurgeable) 129b8e80941Smrg retval = ctx->Driver.TextureObjectPurgeable(ctx, bufObj, option); 130b8e80941Smrg 131b8e80941Smrg return retval; 132b8e80941Smrg} 133b8e80941Smrg 134b8e80941Smrg 135b8e80941SmrgGLenum GLAPIENTRY 136b8e80941Smrg_mesa_ObjectPurgeableAPPLE(GLenum objectType, GLuint name, GLenum option) 137b8e80941Smrg{ 138b8e80941Smrg GLenum retval; 139b8e80941Smrg 140b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 141b8e80941Smrg ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0); 142b8e80941Smrg 143b8e80941Smrg if (name == 0) { 144b8e80941Smrg _mesa_error(ctx, GL_INVALID_VALUE, 145b8e80941Smrg "glObjectPurgeable(name = 0x%x)", name); 146b8e80941Smrg return 0; 147b8e80941Smrg } 148b8e80941Smrg 149b8e80941Smrg switch (option) { 150b8e80941Smrg case GL_VOLATILE_APPLE: 151b8e80941Smrg case GL_RELEASED_APPLE: 152b8e80941Smrg /* legal */ 153b8e80941Smrg break; 154b8e80941Smrg default: 155b8e80941Smrg _mesa_error(ctx, GL_INVALID_ENUM, 156b8e80941Smrg "glObjectPurgeable(name = 0x%x) invalid option: %d", 157b8e80941Smrg name, option); 158b8e80941Smrg return 0; 159b8e80941Smrg } 160b8e80941Smrg 161b8e80941Smrg switch (objectType) { 162b8e80941Smrg case GL_TEXTURE: 163b8e80941Smrg retval = texture_object_purgeable(ctx, name, option); 164b8e80941Smrg break; 165b8e80941Smrg case GL_RENDERBUFFER_EXT: 166b8e80941Smrg retval = renderbuffer_purgeable(ctx, name, option); 167b8e80941Smrg break; 168b8e80941Smrg case GL_BUFFER_OBJECT_APPLE: 169b8e80941Smrg retval = buffer_object_purgeable(ctx, name, option); 170b8e80941Smrg break; 171b8e80941Smrg default: 172b8e80941Smrg _mesa_error(ctx, GL_INVALID_ENUM, 173b8e80941Smrg "glObjectPurgeable(name = 0x%x) invalid type: %d", 174b8e80941Smrg name, objectType); 175b8e80941Smrg return 0; 176b8e80941Smrg } 177b8e80941Smrg 178b8e80941Smrg /* In strict conformance to the spec, we must only return VOLATILE when 179b8e80941Smrg * when passed the VOLATILE option. Madness. 180b8e80941Smrg * 181b8e80941Smrg * XXX First fix the spec, then fix me. 182b8e80941Smrg */ 183b8e80941Smrg return option == GL_VOLATILE_APPLE ? GL_VOLATILE_APPLE : retval; 184b8e80941Smrg} 185b8e80941Smrg 186b8e80941Smrg 187b8e80941Smrgstatic GLenum 188b8e80941Smrgbuffer_object_unpurgeable(struct gl_context *ctx, GLuint name, GLenum option) 189b8e80941Smrg{ 190b8e80941Smrg struct gl_buffer_object *bufObj; 191b8e80941Smrg GLenum retval; 192b8e80941Smrg 193b8e80941Smrg bufObj = _mesa_lookup_bufferobj(ctx, name); 194b8e80941Smrg if (!bufObj) { 195b8e80941Smrg _mesa_error(ctx, GL_INVALID_VALUE, 196b8e80941Smrg "glObjectUnpurgeable(name = 0x%x)", name); 197b8e80941Smrg return 0; 198b8e80941Smrg } 199b8e80941Smrg 200b8e80941Smrg if (! bufObj->Purgeable) { 201b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 202b8e80941Smrg "glObjectUnpurgeable(name = 0x%x) object is " 203b8e80941Smrg " already \"unpurged\"", name); 204b8e80941Smrg return 0; 205b8e80941Smrg } 206b8e80941Smrg 207b8e80941Smrg bufObj->Purgeable = GL_FALSE; 208b8e80941Smrg 209b8e80941Smrg retval = option; 210b8e80941Smrg if (ctx->Driver.BufferObjectUnpurgeable) 211b8e80941Smrg retval = ctx->Driver.BufferObjectUnpurgeable(ctx, bufObj, option); 212b8e80941Smrg 213b8e80941Smrg return retval; 214b8e80941Smrg} 215b8e80941Smrg 216b8e80941Smrg 217b8e80941Smrgstatic GLenum 218b8e80941Smrgrenderbuffer_unpurgeable(struct gl_context *ctx, GLuint name, GLenum option) 219b8e80941Smrg{ 220b8e80941Smrg struct gl_renderbuffer *bufObj; 221b8e80941Smrg GLenum retval; 222b8e80941Smrg 223b8e80941Smrg bufObj = _mesa_lookup_renderbuffer(ctx, name); 224b8e80941Smrg if (!bufObj) { 225b8e80941Smrg _mesa_error(ctx, GL_INVALID_VALUE, 226b8e80941Smrg "glObjectUnpurgeable(name = 0x%x)", name); 227b8e80941Smrg return 0; 228b8e80941Smrg } 229b8e80941Smrg 230b8e80941Smrg if (! bufObj->Purgeable) { 231b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 232b8e80941Smrg "glObjectUnpurgeable(name = 0x%x) object is " 233b8e80941Smrg " already \"unpurged\"", name); 234b8e80941Smrg return 0; 235b8e80941Smrg } 236b8e80941Smrg 237b8e80941Smrg bufObj->Purgeable = GL_FALSE; 238b8e80941Smrg 239b8e80941Smrg retval = option; 240b8e80941Smrg if (ctx->Driver.RenderObjectUnpurgeable) 241b8e80941Smrg retval = ctx->Driver.RenderObjectUnpurgeable(ctx, bufObj, option); 242b8e80941Smrg 243b8e80941Smrg return retval; 244b8e80941Smrg} 245b8e80941Smrg 246b8e80941Smrg 247b8e80941Smrgstatic GLenum 248b8e80941Smrgtexture_object_unpurgeable(struct gl_context *ctx, GLuint name, GLenum option) 249b8e80941Smrg{ 250b8e80941Smrg struct gl_texture_object *bufObj; 251b8e80941Smrg GLenum retval; 252b8e80941Smrg 253b8e80941Smrg bufObj = _mesa_lookup_texture(ctx, name); 254b8e80941Smrg if (!bufObj) { 255b8e80941Smrg _mesa_error(ctx, GL_INVALID_VALUE, 256b8e80941Smrg "glObjectUnpurgeable(name = 0x%x)", name); 257b8e80941Smrg return 0; 258b8e80941Smrg } 259b8e80941Smrg 260b8e80941Smrg if (! bufObj->Purgeable) { 261b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 262b8e80941Smrg "glObjectUnpurgeable(name = 0x%x) object is" 263b8e80941Smrg " already \"unpurged\"", name); 264b8e80941Smrg return 0; 265b8e80941Smrg } 266b8e80941Smrg 267b8e80941Smrg bufObj->Purgeable = GL_FALSE; 268b8e80941Smrg 269b8e80941Smrg retval = option; 270b8e80941Smrg if (ctx->Driver.TextureObjectUnpurgeable) 271b8e80941Smrg retval = ctx->Driver.TextureObjectUnpurgeable(ctx, bufObj, option); 272b8e80941Smrg 273b8e80941Smrg return retval; 274b8e80941Smrg} 275b8e80941Smrg 276b8e80941Smrg 277b8e80941SmrgGLenum GLAPIENTRY 278b8e80941Smrg_mesa_ObjectUnpurgeableAPPLE(GLenum objectType, GLuint name, GLenum option) 279b8e80941Smrg{ 280b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 281b8e80941Smrg ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0); 282b8e80941Smrg 283b8e80941Smrg if (name == 0) { 284b8e80941Smrg _mesa_error(ctx, GL_INVALID_VALUE, 285b8e80941Smrg "glObjectUnpurgeable(name = 0x%x)", name); 286b8e80941Smrg return 0; 287b8e80941Smrg } 288b8e80941Smrg 289b8e80941Smrg switch (option) { 290b8e80941Smrg case GL_RETAINED_APPLE: 291b8e80941Smrg case GL_UNDEFINED_APPLE: 292b8e80941Smrg /* legal */ 293b8e80941Smrg break; 294b8e80941Smrg default: 295b8e80941Smrg _mesa_error(ctx, GL_INVALID_ENUM, 296b8e80941Smrg "glObjectUnpurgeable(name = 0x%x) invalid option: %d", 297b8e80941Smrg name, option); 298b8e80941Smrg return 0; 299b8e80941Smrg } 300b8e80941Smrg 301b8e80941Smrg switch (objectType) { 302b8e80941Smrg case GL_BUFFER_OBJECT_APPLE: 303b8e80941Smrg return buffer_object_unpurgeable(ctx, name, option); 304b8e80941Smrg case GL_TEXTURE: 305b8e80941Smrg return texture_object_unpurgeable(ctx, name, option); 306b8e80941Smrg case GL_RENDERBUFFER_EXT: 307b8e80941Smrg return renderbuffer_unpurgeable(ctx, name, option); 308b8e80941Smrg default: 309b8e80941Smrg _mesa_error(ctx, GL_INVALID_ENUM, 310b8e80941Smrg "glObjectUnpurgeable(name = 0x%x) invalid type: %d", 311b8e80941Smrg name, objectType); 312b8e80941Smrg return 0; 313b8e80941Smrg } 314b8e80941Smrg} 315b8e80941Smrg 316b8e80941Smrg 317b8e80941Smrgstatic void 318b8e80941Smrgget_buffer_object_parameteriv(struct gl_context *ctx, GLuint name, 319b8e80941Smrg GLenum pname, GLint *params) 320b8e80941Smrg{ 321b8e80941Smrg struct gl_buffer_object *bufObj = _mesa_lookup_bufferobj(ctx, name); 322b8e80941Smrg if (!bufObj) { 323b8e80941Smrg _mesa_error(ctx, GL_INVALID_VALUE, 324b8e80941Smrg "glGetObjectParameteriv(name = 0x%x) invalid object", name); 325b8e80941Smrg return; 326b8e80941Smrg } 327b8e80941Smrg 328b8e80941Smrg switch (pname) { 329b8e80941Smrg case GL_PURGEABLE_APPLE: 330b8e80941Smrg *params = bufObj->Purgeable; 331b8e80941Smrg break; 332b8e80941Smrg default: 333b8e80941Smrg _mesa_error(ctx, GL_INVALID_ENUM, 334b8e80941Smrg "glGetObjectParameteriv(name = 0x%x) invalid enum: %d", 335b8e80941Smrg name, pname); 336b8e80941Smrg break; 337b8e80941Smrg } 338b8e80941Smrg} 339b8e80941Smrg 340b8e80941Smrg 341b8e80941Smrgstatic void 342b8e80941Smrgget_renderbuffer_parameteriv(struct gl_context *ctx, GLuint name, 343b8e80941Smrg GLenum pname, GLint *params) 344b8e80941Smrg{ 345b8e80941Smrg struct gl_renderbuffer *rb = _mesa_lookup_renderbuffer(ctx, name); 346b8e80941Smrg if (!rb) { 347b8e80941Smrg _mesa_error(ctx, GL_INVALID_VALUE, 348b8e80941Smrg "glObjectUnpurgeable(name = 0x%x)", name); 349b8e80941Smrg return; 350b8e80941Smrg } 351b8e80941Smrg 352b8e80941Smrg switch (pname) { 353b8e80941Smrg case GL_PURGEABLE_APPLE: 354b8e80941Smrg *params = rb->Purgeable; 355b8e80941Smrg break; 356b8e80941Smrg default: 357b8e80941Smrg _mesa_error(ctx, GL_INVALID_ENUM, 358b8e80941Smrg "glGetObjectParameteriv(name = 0x%x) invalid enum: %d", 359b8e80941Smrg name, pname); 360b8e80941Smrg break; 361b8e80941Smrg } 362b8e80941Smrg} 363b8e80941Smrg 364b8e80941Smrg 365b8e80941Smrgstatic void 366b8e80941Smrgget_texture_object_parameteriv(struct gl_context *ctx, GLuint name, 367b8e80941Smrg GLenum pname, GLint *params) 368b8e80941Smrg{ 369b8e80941Smrg struct gl_texture_object *texObj = _mesa_lookup_texture(ctx, name); 370b8e80941Smrg if (!texObj) { 371b8e80941Smrg _mesa_error(ctx, GL_INVALID_VALUE, 372b8e80941Smrg "glObjectUnpurgeable(name = 0x%x)", name); 373b8e80941Smrg return; 374b8e80941Smrg } 375b8e80941Smrg 376b8e80941Smrg switch (pname) { 377b8e80941Smrg case GL_PURGEABLE_APPLE: 378b8e80941Smrg *params = texObj->Purgeable; 379b8e80941Smrg break; 380b8e80941Smrg default: 381b8e80941Smrg _mesa_error(ctx, GL_INVALID_ENUM, 382b8e80941Smrg "glGetObjectParameteriv(name = 0x%x) invalid enum: %d", 383b8e80941Smrg name, pname); 384b8e80941Smrg break; 385b8e80941Smrg } 386b8e80941Smrg} 387b8e80941Smrg 388b8e80941Smrg 389b8e80941Smrgvoid GLAPIENTRY 390b8e80941Smrg_mesa_GetObjectParameterivAPPLE(GLenum objectType, GLuint name, GLenum pname, 391b8e80941Smrg GLint *params) 392b8e80941Smrg{ 393b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 394b8e80941Smrg 395b8e80941Smrg if (name == 0) { 396b8e80941Smrg _mesa_error(ctx, GL_INVALID_VALUE, 397b8e80941Smrg "glGetObjectParameteriv(name = 0x%x)", name); 398b8e80941Smrg return; 399b8e80941Smrg } 400b8e80941Smrg 401b8e80941Smrg switch (objectType) { 402b8e80941Smrg case GL_TEXTURE: 403b8e80941Smrg get_texture_object_parameteriv(ctx, name, pname, params); 404b8e80941Smrg break; 405b8e80941Smrg case GL_BUFFER_OBJECT_APPLE: 406b8e80941Smrg get_buffer_object_parameteriv(ctx, name, pname, params); 407b8e80941Smrg break; 408b8e80941Smrg case GL_RENDERBUFFER_EXT: 409b8e80941Smrg get_renderbuffer_parameteriv(ctx, name, pname, params); 410b8e80941Smrg break; 411b8e80941Smrg default: 412b8e80941Smrg _mesa_error(ctx, GL_INVALID_ENUM, 413b8e80941Smrg "glGetObjectParameteriv(name = 0x%x) invalid type: %d", 414b8e80941Smrg name, objectType); 415b8e80941Smrg } 416b8e80941Smrg} 417