Added support for explicit length arguments in functions that map buffer objects.

Simplified CachedResult handling of functions that map buffer object ranges.
Improved documentation of CachedResult functions.
This commit is contained in:
Ioannis Tsakpinis 2010-01-04 18:47:49 +00:00
parent f970b8ba42
commit d97fc05a7b
13 changed files with 195 additions and 60 deletions

View File

@ -71,6 +71,12 @@ class GLChecks {
return scratch_buffer.get(0); return scratch_buffer.get(0);
} }
static int getBufferObjectSizeATI(ContextCapabilities caps, int buffer) {
IntBuffer scratch_buffer = caps.scratch_int_buffer;
ATIVertexArrayObject.glGetObjectBufferATI(buffer, ATIVertexArrayObject.GL_OBJECT_BUFFER_SIZE_ATI, scratch_buffer);
return scratch_buffer.get(0);
}
static int getNamedBufferObjectSize(ContextCapabilities caps, int buffer) { static int getNamedBufferObjectSize(ContextCapabilities caps, int buffer) {
IntBuffer scratch_buffer = caps.scratch_int_buffer; IntBuffer scratch_buffer = caps.scratch_int_buffer;
EXTDirectStateAccess.glGetNamedBufferParameterEXT(buffer, GL15.GL_BUFFER_SIZE, scratch_buffer); EXTDirectStateAccess.glGetNamedBufferParameterEXT(buffer, GL15.GL_BUFFER_SIZE, scratch_buffer);

View File

@ -43,4 +43,5 @@ import java.lang.annotation.ElementType;
@Target(ElementType.METHOD) @Target(ElementType.METHOD)
public @interface CachedResult { public @interface CachedResult {
boolean isRange() default false;
} }

View File

@ -91,8 +91,12 @@ public class GeneratorVisitor extends SimpleDeclarationVisitor {
} }
if (Utils.getResultParameter(method) != null && !method.getReturnType().equals(env.getTypeUtils().getVoidType())) if (Utils.getResultParameter(method) != null && !method.getReturnType().equals(env.getTypeUtils().getVoidType()))
throw new RuntimeException(method + " return type is not void but a parameter is annotated with Result"); throw new RuntimeException(method + " return type is not void but a parameter is annotated with Result");
if (method.getAnnotation(CachedResult.class) != null && Utils.getNIOBufferType(Utils.getMethodReturnType(method)) == null) if (method.getAnnotation(CachedResult.class) != null) {
throw new RuntimeException(method + " return type is not a Buffer, but is annotated with CachedResult"); if (Utils.getNIOBufferType(Utils.getMethodReturnType(method)) == null)
throw new RuntimeException(method + " return type is not a Buffer, but is annotated with CachedResult");
if (method.getAnnotation(AutoResultSize.class) == null)
throw new RuntimeException(method + " is annotated with CachedResult but misses an AutoResultSize annotation");
}
validateTypes(method, method.getAnnotationMirrors(), method.getReturnType()); validateTypes(method, method.getAnnotationMirrors(), method.getReturnType());
} }

View File

@ -68,6 +68,9 @@ public class JavaMethodsGenerator {
printMethodWithMultiType(env, type_map, writer, interface_decl, method, typeinfos_instance, Mode.NORMAL, generate_error_checks, context_specific); printMethodWithMultiType(env, type_map, writer, interface_decl, method, typeinfos_instance, Mode.NORMAL, generate_error_checks, context_specific);
} }
} }
if ( method.getAnnotation(CachedResult.class) != null && !method.getAnnotation(CachedResult.class).isRange() ) {
printMethodWithMultiType(env, type_map, writer, interface_decl, method, TypeInfo.getDefaultTypeInfoMap(method), Mode.CACHEDRESULT, generate_error_checks, context_specific);
}
printJavaNativeStub(writer, method, Mode.NORMAL, generate_error_checks, context_specific); printJavaNativeStub(writer, method, Mode.NORMAL, generate_error_checks, context_specific);
if (Utils.hasMethodBufferObjectParameter(method)) { if (Utils.hasMethodBufferObjectParameter(method)) {
printMethodWithMultiType(env, type_map, writer, interface_decl, method, TypeInfo.getDefaultTypeInfoMap(method), Mode.BUFFEROBJECT, generate_error_checks, context_specific); printMethodWithMultiType(env, type_map, writer, interface_decl, method, TypeInfo.getDefaultTypeInfoMap(method), Mode.BUFFEROBJECT, generate_error_checks, context_specific);
@ -120,16 +123,23 @@ public class JavaMethodsGenerator {
first_parameter = generateParameterJava(writer, param, type_info, native_stub, first_parameter, mode); first_parameter = generateParameterJava(writer, param, type_info, native_stub, first_parameter, mode);
} }
} }
CachedResult cached_result_annotation = method.getAnnotation(CachedResult.class);
TypeMirror result_type = Utils.getMethodReturnType(method); TypeMirror result_type = Utils.getMethodReturnType(method);
if ((native_stub && Utils.getNIOBufferType(result_type) != null) || Utils.needResultSize(method)) { if ((native_stub && Utils.getNIOBufferType(result_type) != null) || Utils.needResultSize(method)) {
if (!first_parameter) if (cached_result_annotation == null || !cached_result_annotation.isRange()) {
writer.print(", "); if (!first_parameter)
first_parameter = false; writer.print(", ");
writer.print("long " + Utils.RESULT_SIZE_NAME); first_parameter = false;
writer.print("long " + Utils.RESULT_SIZE_NAME);
}
} }
if (method.getAnnotation(CachedResult.class) != null) { if (cached_result_annotation != null) {
if (!first_parameter) if (!first_parameter)
writer.print(", "); writer.print(", ");
if ( mode == Mode.CACHEDRESULT )
writer.print("long " + Utils.CACHED_BUFFER_LENGTH_NAME + ", ");
first_parameter = false; first_parameter = false;
printResultType(writer, method, native_stub); printResultType(writer, method, native_stub);
writer.print(" " + Utils.CACHED_BUFFER_NAME); writer.print(" " + Utils.CACHED_BUFFER_NAME);
@ -403,16 +413,26 @@ public class JavaMethodsGenerator {
first_parameter = printMethodCallArgument(writer, method, param, typeinfos_instance, mode, first_parameter); first_parameter = printMethodCallArgument(writer, method, param, typeinfos_instance, mode, first_parameter);
} }
if (Utils.getNIOBufferType(Utils.getMethodReturnType(method)) != null) { if (Utils.getNIOBufferType(Utils.getMethodReturnType(method)) != null) {
if (!first_parameter) if (method.getAnnotation(CachedResult.class) != null && method.getAnnotation(CachedResult.class).isRange()) {
writer.print(", "); first_parameter = false;
first_parameter = false; Utils.printExtraCallArguments(writer, method, "");
AutoResultSize auto_result_size_annotation = method.getAnnotation(AutoResultSize.class); } else {
String result_size_expression; if (!first_parameter)
if (auto_result_size_annotation == null) writer.print(", ");
result_size_expression = Utils.RESULT_SIZE_NAME; first_parameter = false;
else
result_size_expression = auto_result_size_annotation.value(); String result_size_expression;
Utils.printExtraCallArguments(writer, method, result_size_expression); if ( mode == Mode.CACHEDRESULT )
result_size_expression = Utils.CACHED_BUFFER_LENGTH_NAME;
else {
AutoResultSize auto_result_size_annotation = method.getAnnotation(AutoResultSize.class);
if (auto_result_size_annotation == null)
result_size_expression = Utils.RESULT_SIZE_NAME;
else
result_size_expression = auto_result_size_annotation.value();
}
Utils.printExtraCallArguments(writer, method, result_size_expression);
}
} }
return first_parameter; return first_parameter;
} }

View File

@ -1,31 +1,31 @@
/* /*
* Copyright (c) 2002-2008 LWJGL Project * Copyright (c) 2002-2008 LWJGL Project
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are * modification, are permitted provided that the following conditions are
* met: * met:
* *
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* *
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* *
* * Neither the name of 'LWJGL' nor the names of * * Neither the name of 'LWJGL' nor the names of
* its contributors may be used to endorse or promote products derived * its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission. * from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
@ -34,5 +34,6 @@ package org.lwjgl.util.generator;
public enum Mode { public enum Mode {
BUFFEROBJECT, BUFFEROBJECT,
AUTOS, AUTOS,
CACHEDRESULT, // Used for generating a CachedResult method with an explicit length argument.
NORMAL NORMAL
} }

View File

@ -106,8 +106,10 @@ public class NativeMethodStubsGenerator {
writer.print("(JNIEnv *env, jclass clazz"); writer.print("(JNIEnv *env, jclass clazz");
generateParameters(writer, method.getParameters(), mode); generateParameters(writer, method.getParameters(), mode);
if (Utils.getNIOBufferType(result_type) != null) { if (Utils.getNIOBufferType(result_type) != null) {
writer.print(", jlong " + Utils.RESULT_SIZE_NAME); CachedResult cached_result_annotation = method.getAnnotation(CachedResult.class);
if (method.getAnnotation(CachedResult.class) != null) if (cached_result_annotation == null || !cached_result_annotation.isRange())
writer.print(", jlong " + Utils.RESULT_SIZE_NAME);
if (cached_result_annotation != null)
writer.print(", jobject " + Utils.CACHED_BUFFER_NAME); writer.print(", jobject " + Utils.CACHED_BUFFER_NAME);
} }
if (context_specific) { if (context_specific) {
@ -160,7 +162,10 @@ public class NativeMethodStubsGenerator {
writer.print(Utils.RESULT_VAR_NAME); writer.print(Utils.RESULT_VAR_NAME);
if (Buffer.class.isAssignableFrom(java_result_type)) { if (Buffer.class.isAssignableFrom(java_result_type)) {
writer.print(", "); writer.print(", ");
Utils.printExtraCallArguments(writer, method, Utils.RESULT_SIZE_NAME); if (method.getAnnotation(CachedResult.class) != null && method.getAnnotation(CachedResult.class).isRange())
Utils.printExtraCallArguments(writer, method, method.getAnnotation(AutoResultSize.class).value());
else
Utils.printExtraCallArguments(writer, method, Utils.RESULT_SIZE_NAME);
} }
if (Buffer.class.isAssignableFrom(java_result_type) || if (Buffer.class.isAssignableFrom(java_result_type) ||
String.class.equals(java_result_type)) String.class.equals(java_result_type))

View File

@ -58,13 +58,14 @@ public class Utils {
public static final String BUFFER_OBJECT_PARAMETER_POSTFIX = "_buffer_offset"; public static final String BUFFER_OBJECT_PARAMETER_POSTFIX = "_buffer_offset";
public static final String RESULT_SIZE_NAME = "result_size"; public static final String RESULT_SIZE_NAME = "result_size";
public static final String RESULT_VAR_NAME = "__result"; public static final String RESULT_VAR_NAME = "__result";
public static final String CACHED_BUFFER_LENGTH_NAME = "length";
public static final String CACHED_BUFFER_NAME = "old_buffer"; public static final String CACHED_BUFFER_NAME = "old_buffer";
private static final String OVERLOADED_METHOD_PREFIX = "n"; private static final String OVERLOADED_METHOD_PREFIX = "n";
public static String getTypedefName(MethodDeclaration method) { public static String getTypedefName(MethodDeclaration method) {
return method.getSimpleName() + TYPEDEF_POSTFIX; return method.getSimpleName() + TYPEDEF_POSTFIX;
} }
public static String getFunctionAddressName(InterfaceDeclaration interface_decl, MethodDeclaration method) { public static String getFunctionAddressName(InterfaceDeclaration interface_decl, MethodDeclaration method) {
return interface_decl.getSimpleName() + "_" + method.getSimpleName() + FUNCTION_POINTER_POSTFIX; return interface_decl.getSimpleName() + "_" + method.getSimpleName() + FUNCTION_POINTER_POSTFIX;
} }
@ -201,7 +202,7 @@ public class Utils {
public static boolean needResultSize(MethodDeclaration method) { public static boolean needResultSize(MethodDeclaration method) {
return getNIOBufferType(getMethodReturnType(method)) != null && method.getAnnotation(AutoResultSize.class) == null; return getNIOBufferType(getMethodReturnType(method)) != null && method.getAnnotation(AutoResultSize.class) == null;
} }
public static void printExtraCallArguments(PrintWriter writer, MethodDeclaration method, String size_parameter_name) { public static void printExtraCallArguments(PrintWriter writer, MethodDeclaration method, String size_parameter_name) {
writer.print(size_parameter_name); writer.print(size_parameter_name);
if (method.getAnnotation(CachedResult.class) != null) { if (method.getAnnotation(CachedResult.class) != null) {

View File

@ -104,13 +104,24 @@ public interface ARB_buffer_object {
@GLdouble Buffer data); @GLdouble Buffer data);
/** /**
* glMapBufferARB maps a gl vertex buffer buffer to a ByteBuffer. The oldBuffer argument can be null, * glMapBufferARB maps a GL buffer object to a ByteBuffer. The old_buffer argument can be null,
* in which case a new ByteBuffer will be created, pointing to the returned memory. If oldBuffer is non-null, * in which case a new ByteBuffer will be created, pointing to the returned memory. If old_buffer is non-null,
* it will be returned if it points to the same mapped memory, otherwise a new ByteBuffer is created. That * it will be returned if it points to the same mapped memory and has the same capacity as the buffer object,
* way, an application will normally use glMapBufferARB like this: * otherwise a new ByteBuffer is created. That way, an application will normally use glMapBufferARB like this:
* <p/> * <p/>
* ByteBuffer mapped_buffer; mapped_buffer = glMapBufferARB(..., ..., ..., null); ... // Another map on the same buffer mapped_buffer = glMapBufferARB(..., ..., ..., mapped_buffer); * ByteBuffer mapped_buffer; mapped_buffer = glMapBufferARB(..., ..., null); ... // Another map on the same buffer mapped_buffer = glMapBufferARB(..., ..., mapped_buffer);
* <p/>
* Only ByteBuffers returned from this method are to be passed as the old_buffer argument. User-created ByteBuffers cannot be reused.
* <p/>
* The version of this method without an explicit length argument calls glGetBufferParameterARB internally to
* retrieve the current buffer object size, which may cause a pipeline flush and reduce application performance.
* <p/>
* The version of this method with an explicit length argument is a fast alternative to the one without. No GL call
* is made to retrieve the buffer object size, so the user is responsible for tracking and using the appropriate length.<br>
* Security warning: The length argument should match the buffer object size. Reading from or writing to outside
* the memory region that corresponds to the mapped buffer object will cause native crashes.
* *
* @param length the length of the mapped memory in bytes.
* @param old_buffer A ByteBuffer. If this argument points to the same address and has the same capacity as the new mapping, it will be returned and no new buffer will be created. * @param old_buffer A ByteBuffer. If this argument points to the same address and has the same capacity as the new mapping, it will be returned and no new buffer will be created.
* *
* @return A ByteBuffer representing the mapped buffer memory. * @return A ByteBuffer representing the mapped buffer memory.

View File

@ -45,7 +45,21 @@ public interface ARB_map_buffer_range {
int GL_MAP_FLUSH_EXPLICIT_BIT = 0x0010; int GL_MAP_FLUSH_EXPLICIT_BIT = 0x0010;
int GL_MAP_UNSYNCHRONIZED_BIT = 0x0020; int GL_MAP_UNSYNCHRONIZED_BIT = 0x0020;
@CachedResult /**
* glMapBufferRange maps a GL buffer object range to a ByteBuffer. The old_buffer argument can be null,
* in which case a new ByteBuffer will be created, pointing to the returned memory. If old_buffer is non-null,
* it will be returned if it points to the same mapped memory and has the same capacity as the buffer object,
* otherwise a new ByteBuffer is created. That way, an application will normally use glMapBufferRange like this:
* <p/>
* ByteBuffer mapped_buffer; mapped_buffer = glMapBufferRange(..., ..., ..., ..., null); ... // Another map on the same buffer mapped_buffer = glMapBufferRange(..., ..., ..., ..., mapped_buffer);
* <p/>
* Only ByteBuffers returned from this method are to be passed as the old_buffer argument. User-created ByteBuffers cannot be reused.
*
* @param old_buffer A ByteBuffer. If this argument points to the same address and has the same capacity as the new mapping, it will be returned and no new buffer will be created.
*
* @return A ByteBuffer representing the mapped buffer memory.
*/
@CachedResult(isRange = true)
@GLvoid @GLvoid
@AutoResultSize("length") @AutoResultSize("length")
ByteBuffer glMapBufferRange(@GLenum int target, @GLintptr long offset, @GLsizeiptr long length, @GLbitfield int access); ByteBuffer glMapBufferRange(@GLenum int target, @GLintptr long offset, @GLsizeiptr long length, @GLbitfield int access);

View File

@ -38,19 +38,31 @@ import java.nio.*;
public interface ATI_map_object_buffer { public interface ATI_map_object_buffer {
/** /**
* glMapObjectBufferATI maps a gl object buffer to a ByteBuffer. The oldBuffer argument can be * glMapObjectBufferATI maps an ATI vertex array object to a ByteBuffer. The old_buffer argument can be null,
* null, in which case a new ByteBuffer will be created, pointing to the returned memory. If * in which case a new ByteBuffer will be created, pointing to the returned memory. If old_buffer is non-null,
* oldBuffer is non-null, it will be returned if it points to the same mapped memory, otherwise a * it will be returned if it points to the same mapped memory and has the same capacity as the vertex array object,
* new ByteBuffer is created. * otherwise a new ByteBuffer is created. That way, an application will normally use glMapObjectBufferATI like this:
* <p/>
* ByteBuffer mapped_buffer; mapped_buffer = glMapObjectBufferATI(..., null); ... // Another map on the same buffer mapped_buffer = glMapObjectBufferATI(..., mapped_buffer);
* <p/>
* Only ByteBuffers returned from this method are to be passed as the old_buffer argument. User-created ByteBuffers cannot be reused.
* <p/>
* The version of this method without an explicit length argument calls glGetObjectBufferATI internally to
* retrieve the current vertex array object size, which may cause a pipeline flush and reduce application performance.
* <p/>
* The version of this method with an explicit length argument is a fast alternative to the one without. No GL call
* is made to retrieve the vertex array object size, so the user is responsible for tracking and using the appropriate length.<br>
* Security warning: The length argument should match the vertex array object size. Reading from or writing to outside
* the memory region that corresponds to the mapped vertex array object will cause native crashes.
* *
* @param result_size The size of the buffer area. * @param length the length of the mapped memory in bytes.
* @param old_buffer A ByteBuffer. If this argument points to the same address and has the same capacity as the new mapping, * @param old_buffer A ByteBuffer. If this argument points to the same address and has the same capacity as the new mapping, it will be returned and no new buffer will be created.
* it will be returned and no new buffer will be created.
* *
* @return A ByteBuffer representing the mapped object buffer memory. * @return A ByteBuffer representing the mapped buffer memory.
*/ */
@CachedResult @CachedResult
@GLvoid @GLvoid
@AutoResultSize("GLChecks.getBufferObjectSizeATI(caps, buffer)")
ByteBuffer glMapObjectBufferATI(@GLuint int buffer); ByteBuffer glMapObjectBufferATI(@GLuint int buffer);
void glUnmapObjectBufferATI(@GLuint int buffer); void glUnmapObjectBufferATI(@GLuint int buffer);

View File

@ -778,6 +778,29 @@ public interface EXT_direct_state_access {
@GLfloat @GLfloat
@GLdouble Buffer data); @GLdouble Buffer data);
/**
* glMapNamedBufferEXT maps a GL buffer object to a ByteBuffer. The old_buffer argument can be null,
* in which case a new ByteBuffer will be created, pointing to the returned memory. If old_buffer is non-null,
* it will be returned if it points to the same mapped memory and has the same capacity as the buffer object,
* otherwise a new ByteBuffer is created. That way, an application will normally use glMapNamedBufferEXT like this:
* <p/>
* ByteBuffer mapped_buffer; mapped_buffer = glMapNamedBufferEXT(..., ..., null); ... // Another map on the same buffer mapped_buffer = glMapNamedBufferEXT(..., ..., mapped_buffer);
* <p/>
* Only ByteBuffers returned from this method are to be passed as the old_buffer argument. User-created ByteBuffers cannot be reused.
* <p/>
* The version of this method without an explicit length argument calls glGetNamedBufferParameterEXT internally to
* retrieve the current buffer object size, which may cause a pipeline flush and reduce application performance.
* <p/>
* The version of this method with an explicit length argument is a fast alternative to the one without. No GL call
* is made to retrieve the buffer object size, so the user is responsible for tracking and using the appropriate length.<br>
* Security warning: The length argument should match the buffer object size. Reading from or writing to outside
* the memory region that corresponds to the mapped buffer object will cause native crashes.
*
* @param length the length of the mapped memory in bytes.
* @param old_buffer A ByteBuffer. If this argument points to the same address and has the same capacity as the new mapping, it will be returned and no new buffer will be created.
*
* @return A ByteBuffer representing the mapped buffer memory.
*/
@Dependent("OpenGL15") @Dependent("OpenGL15")
@CachedResult @CachedResult
@GLvoid @GLvoid
@ -1283,8 +1306,22 @@ public interface EXT_direct_state_access {
in name and replace "enum target" parameter with "uint buffer" in name and replace "enum target" parameter with "uint buffer"
*/ */
/**
* glMapNamedBufferRangeEXT maps a GL buffer object range to a ByteBuffer. The old_buffer argument can be null,
* in which case a new ByteBuffer will be created, pointing to the returned memory. If old_buffer is non-null,
* it will be returned if it points to the same mapped memory and has the same capacity as the buffer object,
* otherwise a new ByteBuffer is created. That way, an application will normally use glMapNamedBufferRangeEXT like this:
* <p/>
* ByteBuffer mapped_buffer; mapped_buffer = glMapNamedBufferRangeEXT(..., ..., ..., ..., null); ... // Another map on the same buffer mapped_buffer = glMapNamedBufferRangeEXT(..., ..., ..., ..., mapped_buffer);
* <p/>
* Only ByteBuffers returned from this method are to be passed as the old_buffer argument. User-created ByteBuffers cannot be reused.
*
* @param old_buffer A ByteBuffer. If this argument points to the same address and has the same capacity as the new mapping, it will be returned and no new buffer will be created.
*
* @return A ByteBuffer representing the mapped buffer memory.
*/
@Dependent("OpenGL30") @Dependent("OpenGL30")
@CachedResult @CachedResult(isRange = true)
@GLvoid @GLvoid
@AutoResultSize("length") @AutoResultSize("length")
ByteBuffer glMapNamedBufferRangeEXT(@GLuint int buffer, @GLintptr long offset, @GLsizeiptr long length, @GLbitfield int access); ByteBuffer glMapNamedBufferRangeEXT(@GLuint int buffer, @GLintptr long offset, @GLsizeiptr long length, @GLbitfield int access);

View File

@ -124,16 +124,25 @@ public interface GL15 {
@GLdouble Buffer data); @GLdouble Buffer data);
/** /**
* glMapBuffer maps a gl vertex buffer buffer to a ByteBuffer. The oldBuffer argument can be null, in which case a new * glMapBuffer maps a GL buffer object to a ByteBuffer. The old_buffer argument can be null,
* ByteBuffer will be created, pointing to the returned memory. If oldBuffer is non-null, it will be returned if it points to * in which case a new ByteBuffer will be created, pointing to the returned memory. If old_buffer is non-null,
* the same mapped memory, otherwise a new ByteBuffer is created. That way, an application will normally use glMapBuffer like * it will be returned if it points to the same mapped memory and has the same capacity as the buffer object,
* this: * otherwise a new ByteBuffer is created. That way, an application will normally use glMapBuffer like this:
* <p/> * <p/>
* ByteBuffer mapped_buffer; mapped_buffer = glMapBuffer(..., ..., ..., null); ... // Another map on the same buffer * ByteBuffer mapped_buffer; mapped_buffer = glMapBuffer(..., ..., null); ... // Another map on the same buffer mapped_buffer = glMapBuffer(..., ..., mapped_buffer);
* mapped_buffer = glMapBuffer(..., ..., ..., mapped_buffer); * <p/>
* * Only ByteBuffers returned from this method are to be passed as the old_buffer argument. User-created ByteBuffers cannot be reused.
* @param old_buffer A ByteBuffer. If this argument points to the same address and has the same capacity as the new mapping, it will be returned and no * <p/>
* new buffer will be created. * The version of this method without an explicit length argument calls glGetBufferParameter internally to
* retrieve the current buffer object size, which may cause a pipeline flush and reduce application performance.
* <p/>
* The version of this method with an explicit length argument is a fast alternative to the one without. No GL call
* is made to retrieve the buffer object size, so the user is responsible for tracking and using the appropriate length.<br>
* Security warning: The length argument should match the buffer object size. Reading from or writing to outside
* the memory region that corresponds to the mapped buffer object will cause native crashes.
*
* @param length the length of the mapped memory in bytes.
* @param old_buffer A ByteBuffer. If this argument points to the same address and has the same capacity as the new mapping, it will be returned and no new buffer will be created.
* *
* @return A ByteBuffer representing the mapped buffer memory. * @return A ByteBuffer representing the mapped buffer memory.
*/ */

View File

@ -240,7 +240,21 @@ public interface GL30 {
int GL_MAP_FLUSH_EXPLICIT_BIT = 0x0010; int GL_MAP_FLUSH_EXPLICIT_BIT = 0x0010;
int GL_MAP_UNSYNCHRONIZED_BIT = 0x0020; int GL_MAP_UNSYNCHRONIZED_BIT = 0x0020;
@CachedResult /**
* glMapBufferRange maps a GL buffer object range to a ByteBuffer. The old_buffer argument can be null,
* in which case a new ByteBuffer will be created, pointing to the returned memory. If old_buffer is non-null,
* it will be returned if it points to the same mapped memory and has the same capacity as the buffer object,
* otherwise a new ByteBuffer is created. That way, an application will normally use glMapBufferRange like this:
* <p/>
* ByteBuffer mapped_buffer; mapped_buffer = glMapBufferRange(..., ..., ..., ..., null); ... // Another map on the same buffer mapped_buffer = glMapBufferRange(..., ..., ..., ..., mapped_buffer);
* <p/>
* Only ByteBuffers returned from this method are to be passed as the old_buffer argument. User-created ByteBuffers cannot be reused.
*
* @param old_buffer A ByteBuffer. If this argument points to the same address and has the same capacity as the new mapping, it will be returned and no new buffer will be created.
*
* @return A ByteBuffer representing the mapped buffer memory.
*/
@CachedResult(isRange = true)
@GLvoid @GLvoid
@AutoResultSize("length") @AutoResultSize("length")
ByteBuffer glMapBufferRange(@GLenum int target, @GLintptr long offset, @GLsizeiptr long length, @GLbitfield int access); ByteBuffer glMapBufferRange(@GLenum int target, @GLintptr long offset, @GLsizeiptr long length, @GLbitfield int access);