APPLE_object_purgeable: core
authorChris Wilson <chris@chris-wilson.co.uk>
Fri, 13 Nov 2009 12:19:35 +0000 (12:19 +0000)
committerChris Wilson <chris@chris-wilson.co.uk>
Fri, 5 Mar 2010 11:23:55 +0000 (11:23 +0000)
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
src/mesa/main/api_exec.c
src/mesa/main/bufferobj.c
src/mesa/main/bufferobj.h
src/mesa/main/dd.h
src/mesa/main/dlist.c
src/mesa/main/extensions.c
src/mesa/main/mfeatures.h
src/mesa/main/mtypes.h

index 70c154b62b2f0030a4bc7b18aa8ef513cf7a501b..fa8d409caa8c8ebae59f81f816be4b2be4585948 100644 (file)
@@ -758,4 +758,10 @@ _mesa_init_exec_table(struct _glapi_table *exec)
    SET_EGLImageTargetTexture2DOES(exec, _mesa_EGLImageTargetTexture2DOES);
    SET_EGLImageTargetRenderbufferStorageOES(exec, _mesa_EGLImageTargetRenderbufferStorageOES);
 #endif
+
+#if FEATURE_APPLE_object_purgeable
+   SET_ObjectPurgeableAPPLE(exec, _mesa_ObjectPurgeableAPPLE);
+   SET_ObjectUnpurgeableAPPLE(exec, _mesa_ObjectUnpurgeableAPPLE);
+   SET_GetObjectParameterivAPPLE(exec, _mesa_GetObjectParameterivAPPLE);
+#endif
 }
index 971b280f3bbc249cd663f034d66f682d77f6046b..3c48f6cce58a69dedcee826a305ac801473822a0 100644 (file)
@@ -37,6 +37,8 @@
 #include "image.h"
 #include "context.h"
 #include "bufferobj.h"
+#include "fbobject.h"
+#include "texobj.h"
 
 
 /* Debug flags */
@@ -1710,3 +1712,357 @@ _mesa_FlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length)
    if (ctx->Driver.FlushMappedBufferRange)
       ctx->Driver.FlushMappedBufferRange(ctx, target, offset, length, bufObj);
 }
+
+#if FEATURE_APPLE_object_purgeable
+static GLenum
+_mesa_BufferObjectPurgeable(GLcontext *ctx, GLuint name, GLenum option)
+{
+   struct gl_buffer_object *bufObj;
+   GLenum retval;
+
+   bufObj = _mesa_lookup_bufferobj(ctx, name);
+   if (!bufObj) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "glObjectPurgeable(name = 0x%x)", name);
+      return 0;
+   }
+   if (!_mesa_is_bufferobj(bufObj)) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glObjectPurgeable(buffer 0)" );
+      return 0;
+   }
+
+   if (bufObj->Purgeable) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glObjectPurgeable(name = 0x%x) is already purgeable", name);
+      return GL_VOLATILE_APPLE;
+   }
+
+   bufObj->Purgeable = GL_TRUE;
+
+   retval = GL_VOLATILE_APPLE;
+   if (ctx->Driver.BufferObjectPurgeable)
+      retval = ctx->Driver.BufferObjectPurgeable(ctx, bufObj, option);
+
+   return retval;
+}
+
+static GLenum
+_mesa_RenderObjectPurgeable(GLcontext *ctx, GLuint name, GLenum option)
+{
+   struct gl_renderbuffer *bufObj;
+   GLenum retval;
+
+   bufObj = _mesa_lookup_renderbuffer(ctx, name);
+   if (!bufObj) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "glObjectUnpurgeable(name = 0x%x)", name);
+      return 0;
+   }
+
+   if (bufObj->Purgeable) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glObjectPurgeable(name = 0x%x) is already purgeable", name);
+      return GL_VOLATILE_APPLE;
+   }
+
+   bufObj->Purgeable = GL_TRUE;
+
+   retval = GL_VOLATILE_APPLE;
+   if (ctx->Driver.RenderObjectPurgeable)
+      retval = ctx->Driver.RenderObjectPurgeable(ctx, bufObj, option);
+
+   return retval;
+}
+
+static GLenum
+_mesa_TextureObjectPurgeable(GLcontext *ctx, GLuint name, GLenum option)
+{
+   struct gl_texture_object *bufObj;
+   GLenum retval;
+
+   bufObj = _mesa_lookup_texture(ctx, name);
+   if (!bufObj) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "glObjectPurgeable(name = 0x%x)", name);
+      return 0;
+   }
+
+   if (bufObj->Purgeable) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glObjectPurgeable(name = 0x%x) is already purgeable", name);
+      return GL_VOLATILE_APPLE;
+   }
+
+   bufObj->Purgeable = GL_TRUE;
+
+   retval = GL_VOLATILE_APPLE;
+   if (ctx->Driver.TextureObjectPurgeable)
+      retval = ctx->Driver.TextureObjectPurgeable(ctx, bufObj, option);
+
+   return retval;
+}
+
+GLenum GLAPIENTRY
+_mesa_ObjectPurgeableAPPLE(GLenum objectType, GLuint name, GLenum option)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0);
+
+   if (name == 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "glObjectPurgeable(name = 0x%x)", name);
+      return 0;
+   }
+
+   switch (option) {
+   case GL_VOLATILE_APPLE:
+   case GL_RELEASED_APPLE:
+      break;
+
+   default:
+      _mesa_error(ctx, GL_INVALID_ENUM,
+                  "glObjectPurgeable(name = 0x%x) invalid option: %d", name, option);
+      return 0;
+   }
+
+   switch (objectType) {
+   case GL_TEXTURE:
+      return _mesa_TextureObjectPurgeable (ctx, name, option);
+   case GL_RENDERBUFFER_EXT:
+      return _mesa_RenderObjectPurgeable (ctx, name, option);
+   case GL_BUFFER_OBJECT_APPLE:
+      return _mesa_BufferObjectPurgeable (ctx, name, option);
+
+   default:
+      _mesa_error(ctx, GL_INVALID_ENUM,
+                  "glObjectPurgeable(name = 0x%x) invalid type: %d", name, objectType);
+      return 0;
+   }
+}
+
+static GLenum
+_mesa_BufferObjectUnpurgeable(GLcontext *ctx, GLuint name, GLenum option)
+{
+   struct gl_buffer_object *bufObj;
+   GLenum retval;
+
+   bufObj = _mesa_lookup_bufferobj(ctx, name);
+   if (!bufObj) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "glObjectUnpurgeable(name = 0x%x)", name);
+      return 0;
+   }
+
+   if (! bufObj->Purgeable) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glObjectUnpurgeable(name = 0x%x) object is already \"unpurged\"", name);
+      return 0;
+   }
+
+   bufObj->Purgeable = GL_FALSE;
+
+   retval = GL_RETAINED_APPLE;
+   if (ctx->Driver.BufferObjectUnpurgeable)
+      retval = ctx->Driver.BufferObjectUnpurgeable(ctx, bufObj, option);
+
+   return retval;
+}
+
+static GLenum
+_mesa_RenderObjectUnpurgeable(GLcontext *ctx, GLuint name, GLenum option)
+{
+   struct gl_renderbuffer *bufObj;
+   GLenum retval;
+
+   bufObj = _mesa_lookup_renderbuffer(ctx, name);
+   if (!bufObj) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "glObjectUnpurgeable(name = 0x%x)", name);
+      return 0;
+   }
+
+   if (! bufObj->Purgeable) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glObjectUnpurgeable(name = 0x%x) object is already \"unpurged\"", name);
+      return 0;
+   }
+
+   bufObj->Purgeable = GL_FALSE;
+
+   retval = GL_RETAINED_APPLE;
+   if (ctx->Driver.RenderObjectUnpurgeable)
+      retval = ctx->Driver.RenderObjectUnpurgeable(ctx, bufObj, option);
+
+   return retval;
+}
+
+static GLenum
+_mesa_TextureObjectUnpurgeable(GLcontext *ctx, GLuint name, GLenum option)
+{
+   struct gl_texture_object *bufObj;
+   GLenum retval;
+
+   bufObj = _mesa_lookup_texture(ctx, name);
+   if (!bufObj) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "glObjectUnpurgeable(name = 0x%x)", name);
+      return 0;
+   }
+
+   if (! bufObj->Purgeable) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glObjectUnpurgeable(name = 0x%x) object is already \"unpurged\"", name);
+      return 0;
+   }
+
+   bufObj->Purgeable = GL_FALSE;
+
+   retval = GL_RETAINED_APPLE;
+   if (ctx->Driver.TextureObjectUnpurgeable)
+      retval = ctx->Driver.TextureObjectUnpurgeable(ctx, bufObj, option);
+
+   return retval;
+}
+
+GLenum GLAPIENTRY
+_mesa_ObjectUnpurgeableAPPLE(GLenum objectType, GLuint name, GLenum option)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0);
+
+   if (name == 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "glObjectUnpurgeable(name = 0x%x)", name);
+      return 0;
+   }
+
+   switch (option) {
+   case GL_RETAINED_APPLE:
+   case GL_UNDEFINED_APPLE:
+      break;
+
+   default:
+      _mesa_error(ctx, GL_INVALID_ENUM,
+                  "glObjectUnpurgeable(name = 0x%x) invalid option: %d", name, option);
+      return 0;
+   }
+
+   switch (objectType) {
+   case GL_BUFFER_OBJECT_APPLE:
+      return _mesa_BufferObjectUnpurgeable(ctx, name, option);
+
+   case GL_TEXTURE:
+      return _mesa_TextureObjectUnpurgeable(ctx, name, option);
+
+   case GL_RENDERBUFFER_EXT:
+      return _mesa_RenderObjectUnpurgeable(ctx, name, option);
+
+   default:
+      _mesa_error(ctx, GL_INVALID_ENUM,
+                  "glObjectUnpurgeable(name = 0x%x) invalid type: %d", name, objectType);
+      return 0;
+   }
+}
+
+static void
+_mesa_GetBufferObjectParameterivAPPLE(GLcontext *ctx, GLuint name, GLenum pname, GLint* params)
+{
+   struct gl_buffer_object *bufObj;
+
+   bufObj = _mesa_lookup_bufferobj(ctx, name);
+   if (!bufObj) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "glGetObjectParameteriv(name = 0x%x) invalid object", name);
+      return;
+   }
+
+   switch (pname) {
+   case GL_PURGEABLE_APPLE:
+      *params = bufObj->Purgeable;
+      break;
+
+   default:
+      _mesa_error(ctx, GL_INVALID_ENUM,
+                  "glGetObjectParameteriv(name = 0x%x) invalid enum: %d", name, pname);
+      break;
+   }
+}
+
+static void
+_mesa_GetRenderObjectParameterivAPPLE(GLcontext *ctx, GLuint name, GLenum pname, GLint* params)
+{
+   struct gl_renderbuffer *bufObj;
+
+   bufObj = _mesa_lookup_renderbuffer(ctx, name);
+   if (!bufObj) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "glObjectUnpurgeable(name = 0x%x)", name);
+      return;
+   }
+
+   switch (pname) {
+   case GL_PURGEABLE_APPLE:
+      *params = bufObj->Purgeable;
+      break;
+
+   default:
+      _mesa_error(ctx, GL_INVALID_ENUM,
+                  "glGetObjectParameteriv(name = 0x%x) invalid enum: %d", name, pname);
+      break;
+   }
+}
+
+static void
+_mesa_GetTextureObjectParameterivAPPLE(GLcontext *ctx, GLuint name, GLenum pname, GLint* params)
+{
+   struct gl_texture_object *bufObj;
+
+   bufObj = _mesa_lookup_texture(ctx, name);
+   if (!bufObj) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "glObjectUnpurgeable(name = 0x%x)", name);
+      return;
+   }
+
+   switch (pname) {
+   case GL_PURGEABLE_APPLE:
+      *params = bufObj->Purgeable;
+      break;
+
+   default:
+      _mesa_error(ctx, GL_INVALID_ENUM,
+                  "glGetObjectParameteriv(name = 0x%x) invalid enum: %d", name, pname);
+      break;
+   }
+}
+
+void GLAPIENTRY
+_mesa_GetObjectParameterivAPPLE(GLenum objectType, GLuint name, GLenum pname, GLint* params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+
+   if (name == 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "glGetObjectParameteriv(name = 0x%x)", name);
+      return;
+   }
+
+   switch (objectType) {
+   case GL_TEXTURE:
+      _mesa_GetTextureObjectParameterivAPPLE (ctx, name, pname, params);
+      break;
+
+   case GL_BUFFER_OBJECT_APPLE:
+      _mesa_GetBufferObjectParameterivAPPLE (ctx, name, pname, params);
+      break;
+
+   case GL_RENDERBUFFER_EXT:
+      _mesa_GetRenderObjectParameterivAPPLE (ctx, name, pname, params);
+      break;
+
+   default:
+      _mesa_error(ctx, GL_INVALID_ENUM,
+                  "glGetObjectParameteriv(name = 0x%x) invalid type: %d", name, objectType);
+   }
+}
+#endif
index f8bca5ff717a2b17041c862b2dfbed7b43eb32b2..912529cfdf96668e46455e3d9d6a9c6f11f9c587 100644 (file)
@@ -175,4 +175,15 @@ _mesa_MapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length,
 extern void GLAPIENTRY
 _mesa_FlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length);
 
+#if FEATURE_APPLE_object_purgeable
+extern GLenum GLAPIENTRY
+_mesa_ObjectPurgeableAPPLE(GLenum objectType, GLuint name, GLenum option);
+
+extern GLenum GLAPIENTRY
+_mesa_ObjectUnpurgeableAPPLE(GLenum objectType, GLuint name, GLenum option);
+
+extern void GLAPIENTRY
+_mesa_GetObjectParameterivAPPLE(GLenum objectType, GLuint name, GLenum pname, GLint* params);
+#endif
+
 #endif
index 84b83fe273123a0492a405672673602a03c9548d..197de09b22a81eb0f15b815739ee6070e24d95ae 100644 (file)
@@ -776,6 +776,23 @@ struct dd_function_table {
    /*@}*/
 #endif
 
+   /**
+    * \name Functions for GL_APPLE_object_purgeable
+    */
+#if FEATURE_APPLE_object_purgeable
+   /*@{*/
+   /* variations on ObjectPurgeable */
+   GLenum (*BufferObjectPurgeable)( GLcontext *ctx, struct gl_buffer_object *obj, GLenum option );
+   GLenum (*RenderObjectPurgeable)( GLcontext *ctx, struct gl_renderbuffer *obj, GLenum option );
+   GLenum (*TextureObjectPurgeable)( GLcontext *ctx, struct gl_texture_object *obj, GLenum option );
+
+   /* variations on ObjectUnpurgeable */
+   GLenum (*BufferObjectUnpurgeable)( GLcontext *ctx, struct gl_buffer_object *obj, GLenum option );
+   GLenum (*RenderObjectUnpurgeable)( GLcontext *ctx, struct gl_renderbuffer *obj, GLenum option );
+   GLenum (*TextureObjectUnpurgeable)( GLcontext *ctx, struct gl_texture_object *obj, GLenum option );
+   /*@}*/
+#endif
+
    /**
     * \name Functions for GL_EXT_framebuffer_object
     */
index 673db30f2549f023ccffe051308ae52039cf2426..43aadb1de570a92d548f055fc466a0327e2ad5ba 100644 (file)
@@ -9285,6 +9285,12 @@ _mesa_init_save_table(struct _glapi_table *table)
    /* 364. GL_EXT_provoking_vertex */
    SET_ProvokingVertexEXT(table, save_ProvokingVertexEXT);
 
+   /* 371. GL_APPLE_object_purgeable */
+#if FEATURE_APPLE_object_purgeable
+   SET_ObjectPurgeableAPPLE(table, _mesa_ObjectPurgeableAPPLE);
+   SET_ObjectUnpurgeableAPPLE(table, _mesa_ObjectUnpurgeableAPPLE);
+#endif
+
    /* GL 3.0 */
 #if 0
    SET_ClearBufferiv(table, save_ClearBufferiv);
index 0e7e52a54acb168476e93fad1ae034cca9618a07..30245d6aafa6d8c361685ed33c515a6e747e439f 100644 (file)
@@ -153,6 +153,7 @@ static const struct {
    { OFF, "GL_APPLE_client_storage",           F(APPLE_client_storage) },
    { ON,  "GL_APPLE_packed_pixels",            F(APPLE_packed_pixels) },
    { OFF, "GL_APPLE_vertex_array_object",      F(APPLE_vertex_array_object) },
+   { OFF, "GL_APPLE_object_purgeable",         F(APPLE_object_purgeable) },
    { OFF, "GL_ATI_blend_equation_separate",    F(EXT_blend_equation_separate) },
    { OFF, "GL_ATI_envmap_bumpmap",             F(ATI_envmap_bumpmap) },
    { OFF, "GL_ATI_texture_env_combine3",       F(ATI_texture_env_combine3)},
@@ -265,6 +266,9 @@ _mesa_enable_sw_extensions(GLcontext *ctx)
    ctx->Extensions.ARB_sync = GL_TRUE;
 #endif
    ctx->Extensions.APPLE_vertex_array_object = GL_TRUE;
+#if FEATURE_APPLE_object_purgeable
+   ctx->Extensions.APPLE_object_purgeable = GL_TRUE;
+#endif
    ctx->Extensions.ATI_envmap_bumpmap = GL_TRUE;
 #if FEATURE_ATI_fragment_shader
    ctx->Extensions.ATI_fragment_shader = GL_TRUE;
index f0896ee626fa1424c5eeaf61ff7c0fb68025e88c..cb96c4d1d05e444bc135de94ec37094398a93654 100644 (file)
 #define FEATURE_EXT_framebuffer_blit _HAVE_FULL_GL
 #define FEATURE_EXT_framebuffer_object _HAVE_FULL_GL
 #define FEATURE_EXT_pixel_buffer_object  _HAVE_FULL_GL
+#define FEATURE_APPLE_object_purgeable _HAVE_FULL_GL
 #define FEATURE_EXT_texture_sRGB _HAVE_FULL_GL
 #define FEATURE_ATI_fragment_shader _HAVE_FULL_GL
 #define FEATURE_NV_fence  _HAVE_FULL_GL
index 4d55ebb97227777d98d15bdd7607b69d9790e4c1..9d9b475dd17f6b11a8e8c7420136a383c7c2d692 100644 (file)
@@ -1244,6 +1244,7 @@ struct gl_texture_object
    GLboolean GenerateMipmap;    /**< GL_SGIS_generate_mipmap */
    GLboolean _Complete;                /**< Is texture object complete? */
    GLboolean _RenderToTexture;  /**< Any rendering to this texture? */
+   GLboolean Purgeable;         /**< Is the buffer purgeable under memory pressure? */
 
    /** Actual texture images, indexed by [cube face] and [mipmap level] */
    struct gl_texture_image *Image[MAX_FACES][MAX_TEXTURE_LEVELS];
@@ -1439,6 +1440,7 @@ struct gl_buffer_object
    GLsizeiptr Length;   /**< Mapped length */
    /*@}*/
    GLboolean Written;   /**< Ever written to? (for debugging) */
+   GLboolean Purgeable; /**< Is the buffer purgeable under memory pressure? */
 };
 
 
@@ -2104,6 +2106,7 @@ struct gl_renderbuffer
    GLuint Name;
    GLint RefCount;
    GLuint Width, Height;
+   GLboolean Purgeable;   /**< Is the buffer purgeable under memory pressure? */
 
    GLenum InternalFormat; /**< The user-specified format */
    GLenum _BaseFormat;    /**< Either GL_RGB, GL_RGBA, GL_DEPTH_COMPONENT or
@@ -2491,6 +2494,7 @@ struct gl_extensions
    GLboolean APPLE_client_storage;
    GLboolean APPLE_packed_pixels;
    GLboolean APPLE_vertex_array_object;
+   GLboolean APPLE_object_purgeable;
    GLboolean ATI_envmap_bumpmap;
    GLboolean ATI_texture_mirror_once;
    GLboolean ATI_texture_env_combine3;