1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2012 - ScilabEnterprises - Calixte DENIZET
4  *
5  * Copyright (C) 2012 - 2016 - Scilab Enterprises
6  *
7  * This file is hereby licensed under the terms of the GNU GPL v2.0,
8  * pursuant to article 5.3.4 of the CeCILL v.2.1.
9  * This file was originally licensed under the terms of the CeCILL v2.1,
10  * and continues to be available under such terms.
11  * For more information, see the COPYING file which you should have received
12  * along with this program.
13  */
14 
15 package org.scilab.forge.scirenderer.implementation.g2d.buffers;
16 
17 import org.scilab.forge.scirenderer.buffers.DataBuffer;
18 import org.scilab.forge.scirenderer.buffers.ElementsBuffer;
19 
20 import java.nio.FloatBuffer;
21 
22 /**
23  * @author Calixte DENIZET
24  */
25 @SuppressWarnings(value = { "serial" })
26 public class G2DElementsBuffer implements DataBuffer, ElementsBuffer {
27 
28     /**
29      * The current size of one element.
30      */
31     public static final int ELEMENT_SIZE = 4;
32 
33     /**
34      * The default vertex.
35      */
36     private static final float[] DEFAULT_VERTEX = new float[] {0, 0, 0, 1};
37 
38     /**
39      * the data this buffer contain.
40      */
41     private FloatBuffer data;
42     private final Object mutex;
43 
44     /**
45      * Default constructor.
46      * The constructor is package : only {@link G2DBuffersManager} can instantiate this object.
47      */
G2DElementsBuffer()48     G2DElementsBuffer() {
49         mutex = new Object();
50         data = null;
51     }
52 
53     @Override
setData(float[] newData, int elementSize)54     public void setData(float[] newData, int elementSize) {
55         // Check the given vertex size
56         if ((elementSize < 1) || (elementSize > ELEMENT_SIZE)) {
57             throw new BadElementSizeException(elementSize, 1, ELEMENT_SIZE);
58         }
59 
60         int verticesNumber = newData.length / elementSize;
61         //FloatBuffer buffer = BufferUtil.newFloatBuffer(ELEMENT_SIZE * verticesNumber);
62         FloatBuffer buffer = FloatBuffer.allocate(ELEMENT_SIZE * verticesNumber);
63         buffer.rewind();
64 
65 
66         // Fill buffer with given data.
67         // Missing coordinate are filled with the 'DEFAULT_VERTEX' ones.
68         int k = 0;
69         for (int i = 0; i < verticesNumber; i++) {
70             for (int j = 0; j < ELEMENT_SIZE; j++) {
71                 if (j < elementSize) {
72                     buffer.put(newData[k++]);
73                 } else {
74                     buffer.put(DEFAULT_VERTEX[j]);
75                 }
76             }
77         }
78 
79         buffer.rewind();
80         setData(buffer);
81     }
82 
83     @Override
setData(Float[] newData, int elementSize)84     public void setData(Float[] newData, int elementSize) {
85 
86         // Check the given vertex size
87         if ((elementSize < 1) || (elementSize > ELEMENT_SIZE)) {
88             throw new BadElementSizeException(elementSize, 1, ELEMENT_SIZE);
89         }
90 
91         int verticesNumber = newData.length / elementSize;
92         //FloatBuffer buffer = BufferUtil.newFloatBuffer(ELEMENT_SIZE * verticesNumber);
93         FloatBuffer buffer = FloatBuffer.allocate(ELEMENT_SIZE * verticesNumber);
94         buffer.rewind();
95 
96 
97         // Fill buffer with given data.
98         // Missing coordinate are filled with the 'DEFAULT_VERTEX' ones.
99         int k = 0;
100         for (int i = 0; i < verticesNumber; i++) {
101             for (int j = 0; j < ELEMENT_SIZE; j++) {
102                 if (j < elementSize) {
103                     buffer.put(newData[k++]);
104                 } else {
105                     buffer.put(DEFAULT_VERTEX[j]);
106                 }
107             }
108         }
109 
110         buffer.rewind();
111         setData(buffer);
112     }
113 
114     @Override
setData(FloatBuffer newData, int elementsSize)115     public void setData(FloatBuffer newData, int elementsSize) {
116         // Check the given vertex size
117         if ((elementsSize < 1) || (elementsSize > ELEMENT_SIZE)) {
118             throw new BadElementSizeException(elementsSize, 1, ELEMENT_SIZE);
119         }
120 
121         if (elementsSize == 4) {
122             // No need to complete buffer.
123             if (newData != null) {
124                 newData.rewind();
125             }
126             setData(newData);
127             return;
128         }
129 
130         int verticesNumber = newData.limit() / elementsSize;
131         //FloatBuffer buffer = BufferUtil.newFloatBuffer(ELEMENT_SIZE * verticesNumber);
132         FloatBuffer buffer = FloatBuffer.allocate(ELEMENT_SIZE * verticesNumber);
133         buffer.rewind();
134 
135         // Fill buffer with given data.
136         // Missing coordinate are filled with the 'DEFAULT_VERTEX' ones.
137         newData.rewind();
138         for (int i = 0; i < verticesNumber; i++) {
139             for (int j = 0; j < ELEMENT_SIZE; j++) {
140                 if (j < elementsSize) {
141                     buffer.put(newData.get());
142                 } else {
143                     buffer.put(DEFAULT_VERTEX[j]);
144                 }
145             }
146         }
147 
148         buffer.rewind();
149         setData(buffer);
150     }
151 
152     @Override
getSize()153     public int getSize() {
154         synchronized (mutex) {
155             if (data == null) {
156                 return 0;
157             } else {
158                 return data.limit() / ELEMENT_SIZE;
159             }
160         }
161     }
162 
163     @Override
getElementsSize()164     public int getElementsSize() {
165         return ELEMENT_SIZE;
166     }
167 
168     @Override
getData()169     public FloatBuffer getData() {
170         synchronized (mutex) {
171             if (data != null) {
172                 return data;
173             } else {
174                 return null;
175             }
176         }
177     }
178 
179     /**
180      * Really set the data.
181      * @param data the new data.
182      */
setData(FloatBuffer data)183     private void setData(FloatBuffer data) {
184         synchronized (mutex) {
185             this.data = data;
186         }
187     }
188 
189     /**
190      * A specific runtime exception for bad elements size.
191      */
192     private static class BadElementSizeException extends RuntimeException {
193 
194         /**
195          * Default constructor.
196          * @param size the size given for elements.
197          * @param min  the minimum possible size.
198          * @param max  the upper bound of possible size (excluded of possible size).
199          */
BadElementSizeException(int size, int min, int max)200         public BadElementSizeException(int size, int min, int max) {
201             super("Bad vertex elements  size : " + size + ". Should be in [" + min + ", " + (max - 1) + "]");
202         }
203     }
204 
205     @Override
clear()206     public void clear() {
207         if (data != null) {
208             data.clear();
209         }
210         data = null;
211     }
212 }
213