Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import android.opengl.*;
import com.jme3.renderer.RendererException;
import com.jme3.renderer.opengl.*;
import com.jme3.util.ByteBufferUtils;
import com.jme3.util.BufferUtils;

import java.nio.Buffer;
Expand Down Expand Up @@ -233,7 +234,7 @@ public void glGetBufferSubData(int target, long offset, ByteBuffer data) {
try {
ByteBuffer source = (ByteBuffer) mapped;
source.limit(byteCount);
data.duplicate().put(source);
ByteBufferUtils.duplicate(data).put(source);
} finally {
unmapBufferAfterRead(target);
}
Expand Down Expand Up @@ -414,7 +415,7 @@ public void glGetBoolean(int pname, ByteBuffer params) {
boolean[] values = new boolean[count];
GLES20.glGetBooleanv(pname, values, 0);

ByteBuffer destination = params.duplicate();
ByteBuffer destination = ByteBufferUtils.duplicate(params);
for (boolean value : values) {
destination.put((byte) (value ? GLES20.GL_TRUE : GLES20.GL_FALSE));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import com.jme3.texture.*;
import com.jme3.texture.image.ColorSpace;
import com.jme3.ui.Picture;
import com.jme3.util.ByteBufferUtils;
import com.jme3.util.BufferUtils;
import com.jme3.util.TempVars;

Expand Down Expand Up @@ -155,7 +156,7 @@ public static TextureCubeMap duplicateCubeMap(TextureCubeMap sourceMap) {
Image cubeImage = new Image(srcImg.getFormat(), srcImg.getWidth(), srcImg.getHeight(), null, srcImg.getColorSpace());

for (ByteBuffer d : srcImg.getData()) {
cubeImage.addData(d.duplicate());
cubeImage.addData(ByteBufferUtils.duplicate(d));
}

cubeImage.setMipMapSizes(srcImg.getMipMapSizes());
Expand Down Expand Up @@ -749,5 +750,3 @@ public static TextureCubeMap createPrefilteredEnvMap(int size, Image.Format imag
}
}



Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
import com.jme3.texture.TextureImage;
import com.jme3.texture.image.ColorSpace;
import com.jme3.texture.image.LastTextureState;
import com.jme3.util.ByteBufferUtils;
import com.jme3.util.BufferUtils;
import com.jme3.util.ListMap;
import com.jme3.util.MipMapGenerator;
Expand Down Expand Up @@ -3041,7 +3042,7 @@ private Image cloneImageForUpload(Image image, boolean scaleToPot) {
if (buffer == null) {
return null;
}
data.add(buffer.duplicate());
data.add(ByteBufferUtils.duplicate(buffer));
}
return new Image(image.getFormat(), image.getWidth(), image.getHeight(), image.getDepth(),
data, null, image.getColorSpace());
Expand Down
7 changes: 4 additions & 3 deletions jme3-core/src/main/java/com/jme3/scene/VertexBuffer.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import com.jme3.export.*;
import com.jme3.math.FastMath;
import com.jme3.renderer.Renderer;
import com.jme3.util.ByteBufferUtils;
import com.jme3.util.BufferUtils;
import com.jme3.util.NativeObject;
import java.io.IOException;
Expand Down Expand Up @@ -452,9 +453,9 @@ public void setStride(int stride) {
* Returns the raw internal data buffer used by this VertexBuffer.
* This buffer is not safe to call from multiple threads since buffers
* have their own internal position state that cannot be shared.
* Call getData().duplicate(), getData().asReadOnlyBuffer(), or
* the more convenient getDataReadOnly() if the buffer may be accessed
* from multiple threads.
* Call getData().duplicate() for typed buffers, {@link ByteBufferUtils#duplicate(java.nio.ByteBuffer)}
* for ByteBuffers, getData().asReadOnlyBuffer(), or the more convenient
* getDataReadOnly() if the buffer may be accessed from multiple threads.
*
* @return A native buffer, in the specified {@link Format format}.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import com.jme3.export.OutputCapsule;
import com.jme3.export.Savable;
import com.jme3.renderer.Renderer;
import com.jme3.util.ByteBufferUtils;
import com.jme3.util.BufferUtils;
import com.jme3.util.NativeObject;

Expand Down Expand Up @@ -172,10 +173,10 @@ public void setData(ByteBuffer data) {
}
return;
}
ByteBuffer source = data == this.data ? data.duplicate() : data;
ByteBuffer source = data == this.data ? ByteBufferUtils.duplicate(data) : data;
Comment thread
riccardobl marked this conversation as resolved.
ByteBuffer oldData = this.data;

this.data = BufferUtils.createByteBuffer(source.limit() - source.position());
this.data = BufferUtils.createByteBuffer(source.limit() - source.position()).order(source.order());
this.data.put(source);

if (oldData != null) {
Expand All @@ -199,7 +200,7 @@ public ByteBuffer getData() {
data = BufferUtils.createByteBuffer(regionsEnd + 1);
} else if (data.limit() <= regionsEnd) {
// new buffer
ByteBuffer newData = BufferUtils.createByteBuffer(regionsEnd + 1);
ByteBuffer newData = BufferUtils.createByteBuffer(regionsEnd + 1).order(data.order());

// copy old buffer in new buffer
if (newData.limit() < data.limit()) data.limit(newData.limit());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
*/
package com.jme3.shader.bufferobject;

import com.jme3.util.ByteBufferUtils;

import java.io.IOException;
import java.nio.ByteBuffer;

Expand Down Expand Up @@ -73,7 +75,7 @@ public ByteBuffer getData() {
ByteBuffer source = bo.getData();
assert end < source.capacity() : "Can't set limit at " + end + " on capacity " + source.capacity();

ByteBuffer view = source.duplicate();
ByteBuffer view = ByteBufferUtils.duplicate(source);
view.position(start);
view.limit(end + 1);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
*/
package com.jme3.shader.bufferobject;

import com.jme3.util.ByteBufferUtils;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Iterator;
Expand All @@ -49,7 +51,7 @@ private static class DirtyRegion extends BufferRegion {
@Override
public ByteBuffer getData() {
ByteBuffer source = bo.getData();
ByteBuffer view = source.duplicate();
ByteBuffer view = ByteBufferUtils.duplicate(source);
view.position(start);
view.limit(end + 1);
return view.slice().order(source.order());
Expand Down
55 changes: 55 additions & 0 deletions jme3-core/src/main/java/com/jme3/util/ByteBufferUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright (c) 2009-2026 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jme3.util;

import java.nio.ByteBuffer;

/**
* Utility methods for ByteBuffer views.
*/
public final class ByteBufferUtils {

private ByteBufferUtils() {
}

/**
* Duplicates a ByteBuffer and preserves its byte order.
*
* @param source the buffer to duplicate
* @return a duplicate with independent position, limit, and mark
*/
public static ByteBuffer duplicate(ByteBuffer source) {
ByteBuffer duplicate = source.duplicate();
duplicate.order(source.order());
return duplicate;
}
Comment thread
riccardobl marked this conversation as resolved.
}
10 changes: 5 additions & 5 deletions jme3-core/src/main/java/com/jme3/util/MipMapGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -220,10 +220,10 @@ private static MipChain generateMipChainForSlice(Image sourceImage,
totalSize += size;
}

ByteBuffer combined = BufferUtils.createByteBuffer(totalSize);
ByteBuffer combined = BufferUtils.createByteBuffer(totalSize).order(levels.get(0).order());

for (ByteBuffer level : levels) {
ByteBuffer duplicate = level.duplicate();
ByteBuffer duplicate = ByteBufferUtils.duplicate(level);
duplicate.clear();
combined.put(duplicate);
}
Expand All @@ -246,7 +246,7 @@ private static Image scaleLevel(Image inputImage,
validateImage(inputImage);

int outputSize = levelSize(inputImage.getFormat(), outputWidth, outputHeight);
ByteBuffer outputBuffer = BufferUtils.createByteBuffer(outputSize);
ByteBuffer outputBuffer = BufferUtils.createByteBuffer(outputSize).order(inputImage.getData(inputSlice).order());

Image outputImage = new Image(
inputImage.getFormat(),
Expand Down Expand Up @@ -519,11 +519,11 @@ private static ByteBuffer copyBaseLevel(ByteBuffer source, int baseLevelSize) {
);
}

ByteBuffer duplicate = source.duplicate();
ByteBuffer duplicate = ByteBufferUtils.duplicate(source);
duplicate.clear();
duplicate.limit(baseLevelSize);
Comment thread
riccardobl marked this conversation as resolved.

ByteBuffer copy = BufferUtils.createByteBuffer(baseLevelSize);
ByteBuffer copy = BufferUtils.createByteBuffer(baseLevelSize).order(source.order());
copy.put(duplicate);
copy.flip();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,31 @@ public void testSetDataHandlesSelfAlias() {
assertEquals((byte) 0x44, result.get());
}

@Test
public void testSetDataPreservesSourceOrder() {
BufferObject bo = new BufferObject();
ByteBuffer source = ByteBuffer.allocateDirect(4).order(ByteOrder.LITTLE_ENDIAN);
source.putInt(0x01020304);
source.flip();

bo.setData(source);

ByteBuffer result = bo.getData();
assertEquals(ByteOrder.LITTLE_ENDIAN, result.order());
assertEquals(0x01020304, result.getInt());
}

@Test
public void testGrowingDataPreservesExistingOrder() {
BufferObject bo = new BufferObject();
bo.setRegions(Arrays.asList(new BufferRegion(0, 3)));
bo.getData().order(ByteOrder.LITTLE_ENDIAN);

bo.setRegions(Arrays.asList(new BufferRegion(0, 7)));

assertEquals(ByteOrder.LITTLE_ENDIAN, bo.getData().order());
}

@Test
public void testSetDataNullClearsBuffer() {
BufferObject bo = new BufferObject();
Expand Down
15 changes: 15 additions & 0 deletions jme3-core/src/test/java/com/jme3/util/MipMapGeneratorTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import com.jme3.texture.Image;
import com.jme3.texture.image.ColorSpace;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import org.junit.jupiter.api.Test;

Expand Down Expand Up @@ -74,4 +75,18 @@ public void testGenerateMipMapsRejectsNullDataBuffer() {
assertThrows(IllegalArgumentException.class,
() -> MipMapGenerator.generateMipMaps(image, true, false));
}

@Test
public void testGenerateMipMapsPreservesDataOrder() {
ByteBuffer data = BufferUtils.createByteBuffer(2 * 2 * 4).order(ByteOrder.BIG_ENDIAN);
for (int i = 0; i < data.capacity(); i++) {
data.put((byte) i);
}
data.flip();

Image image = new Image(Image.Format.RGBA8, 2, 2, data, ColorSpace.Linear);
MipMapGenerator.generateMipMaps(image, true, false);

assertEquals(ByteOrder.BIG_ENDIAN, image.getData(0).order());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import com.jme3.system.JmeContext.Type;
import com.jme3.texture.Image;
import com.jme3.texture.image.ColorSpace;
import com.jme3.util.ByteBufferUtils;
import com.jme3.util.res.Resources;

import jme3tools.converters.ImageToAwt;
Expand Down Expand Up @@ -102,7 +103,7 @@ private static BufferedImage ensureOpaque(BufferedImage original) {

@Override
public void writeImageFile(OutputStream outStream, String format, ByteBuffer imageData, int width, int height) throws IOException {
BufferedImage awtImage = ImageToAwt.convert(new Image(Image.Format.RGBA8, width, height, imageData.duplicate(), ColorSpace.Linear), false, true, 0);
BufferedImage awtImage = ImageToAwt.convert(new Image(Image.Format.RGBA8, width, height, ByteBufferUtils.duplicate(imageData), ColorSpace.Linear), false, true, 0);
awtImage = verticalFlip(awtImage);

ImageWriter writer = ImageIO.getImageWritersByFormatName(format).next();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

import com.jme3.network.Filter;
import com.jme3.network.kernel.*;
import com.jme3.util.ByteBufferUtils;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
Expand Down Expand Up @@ -161,7 +162,7 @@ public void broadcast( Filter<? super Endpoint> filter, ByteBuffer data, boolean
// Give it the data... but let each endpoint track their
// own completion over the shared array of bytes by
// duplicating it
p.send( data.duplicate(), false, false );
p.send( ByteBufferUtils.duplicate(data), false, false );
}

// Wake up the selector so it can reinitialize its
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
import com.jme3.scene.VertexBuffer;
import com.jme3.scene.plugins.gltf.GltfLoader.SkinBuffers;
import com.jme3.texture.Texture;
import com.jme3.util.ByteBufferUtils;
import com.jme3.util.BufferUtils;
import com.jme3.util.IntMap;
import com.jme3.util.LittleEndien;
Expand Down Expand Up @@ -1034,7 +1035,7 @@ public static Buffer getBufferView(ByteBuffer source, int byteOffset, int count
boolean tightlyPacked = (stride == elemSize);

if (tightlyPacked) {
ByteBuffer view = source.duplicate();
ByteBuffer view = ByteBufferUtils.duplicate(source);
view.position(start).limit(start + bytes);
view = view.slice().order(ByteOrder.LITTLE_ENDIAN);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import com.jme3.math.FastMath;
import com.jme3.texture.Image;
import com.jme3.texture.image.ColorSpace;
import com.jme3.util.ByteBufferUtils;
import com.jme3.util.BufferUtils;

public class StbImageLoader implements AssetLoader {
Expand Down Expand Up @@ -124,8 +125,7 @@ private static Image.Format selectFormat(int channels, boolean is16bit, boolean
private ByteBuffer convertImageData(StbImageResult imgData, Image.Format jmeFormat) {
int outputSize = jmeFormat.getBitsPerPixel() / 8 * imgData.getWidth() * imgData.getHeight();
ByteBuffer jmeImageBuffer = BufferUtils.createByteBuffer(outputSize);
ByteBuffer source = imgData.getData().duplicate();
source.order(imgData.getData().order());
ByteBuffer source = ByteBufferUtils.duplicate(imgData.getData());
source.position(0).limit(imgData.getDataSize());

if (!imgData.is16Bit() && !imgData.isFloat()) {
Expand Down
Loading