Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/share/classes/sun/java2d/pipe/RenderBuffer.java
41159 views
1
/*
2
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package sun.java2d.pipe;
27
28
import jdk.internal.misc.Unsafe;
29
30
31
/**
32
* The RenderBuffer class is a simplified, high-performance, Unsafe wrapper
33
* used for buffering rendering operations in a single-threaded rendering
34
* environment. It's functionality is similar to the ByteBuffer and related
35
* NIO classes. However, the methods in this class perform little to no
36
* alignment or bounds checks for performance reasons. Therefore, it is
37
* the caller's responsibility to ensure that all put() calls are properly
38
* aligned and within bounds:
39
* - int and float values must be aligned on 4-byte boundaries
40
* - long and double values must be aligned on 8-byte boundaries
41
*
42
* This class only includes the bare minimum of methods to support
43
* single-threaded rendering. For example, there is no put(double[]) method
44
* because we currently have no need for such a method in the STR classes.
45
*/
46
public class RenderBuffer {
47
48
/**
49
* These constants represent the size of various data types (in bytes).
50
*/
51
protected static final long SIZEOF_BYTE = 1L;
52
protected static final long SIZEOF_SHORT = 2L;
53
protected static final long SIZEOF_INT = 4L;
54
protected static final long SIZEOF_FLOAT = 4L;
55
protected static final long SIZEOF_LONG = 8L;
56
protected static final long SIZEOF_DOUBLE = 8L;
57
58
/**
59
* Represents the number of elements at which we have empirically
60
* determined that the average cost of a JNI call exceeds the expense
61
* of an element by element copy. In other words, if the number of
62
* elements in an array to be copied exceeds this value, then we should
63
* use the copyFromArray() method to complete the bulk put operation.
64
* (This value can be adjusted if the cost of JNI downcalls is reduced
65
* in a future release.)
66
*/
67
private static final int COPY_FROM_ARRAY_THRESHOLD = 6;
68
69
protected final Unsafe unsafe;
70
protected final long baseAddress;
71
protected final long endAddress;
72
protected long curAddress;
73
protected final int capacity;
74
75
protected RenderBuffer(int numBytes) {
76
unsafe = Unsafe.getUnsafe();
77
curAddress = baseAddress = unsafe.allocateMemory(numBytes);
78
endAddress = baseAddress + numBytes;
79
capacity = numBytes;
80
}
81
82
/**
83
* Allocates a fresh buffer using the machine endianness.
84
*/
85
public static RenderBuffer allocate(int numBytes) {
86
return new RenderBuffer(numBytes);
87
}
88
89
/**
90
* Returns the base address of the underlying memory buffer.
91
*/
92
public final long getAddress() {
93
return baseAddress;
94
}
95
96
/**
97
* The behavior (and names) of the following methods are nearly
98
* identical to their counterparts in the various NIO Buffer classes.
99
*/
100
101
public final int capacity() {
102
return capacity;
103
}
104
105
public final int remaining() {
106
return (int)(endAddress - curAddress);
107
}
108
109
public final int position() {
110
return (int)(curAddress - baseAddress);
111
}
112
113
public final void position(long numBytes) {
114
curAddress = baseAddress + numBytes;
115
}
116
117
public final void clear() {
118
curAddress = baseAddress;
119
}
120
121
public final RenderBuffer skip(long numBytes) {
122
curAddress += numBytes;
123
return this;
124
}
125
126
/**
127
* putByte() methods...
128
*/
129
130
public final RenderBuffer putByte(byte x) {
131
unsafe.putByte(curAddress, x);
132
curAddress += SIZEOF_BYTE;
133
return this;
134
}
135
136
public RenderBuffer put(byte[] x) {
137
return put(x, 0, x.length);
138
}
139
140
public RenderBuffer put(byte[] x, int offset, int length) {
141
if (length > COPY_FROM_ARRAY_THRESHOLD) {
142
long offsetInBytes = offset * SIZEOF_BYTE + Unsafe.ARRAY_BYTE_BASE_OFFSET;
143
long lengthInBytes = length * SIZEOF_BYTE;
144
unsafe.copyMemory(x, offsetInBytes, null, curAddress, lengthInBytes);
145
position(position() + lengthInBytes);
146
} else {
147
int end = offset + length;
148
for (int i = offset; i < end; i++) {
149
putByte(x[i]);
150
}
151
}
152
return this;
153
}
154
155
/**
156
* putShort() methods...
157
*/
158
159
public final RenderBuffer putShort(short x) {
160
// assert (position() % SIZEOF_SHORT == 0);
161
unsafe.putShort(curAddress, x);
162
curAddress += SIZEOF_SHORT;
163
return this;
164
}
165
166
public RenderBuffer put(short[] x) {
167
return put(x, 0, x.length);
168
}
169
170
public RenderBuffer put(short[] x, int offset, int length) {
171
// assert (position() % SIZEOF_SHORT == 0);
172
if (length > COPY_FROM_ARRAY_THRESHOLD) {
173
long offsetInBytes = offset * SIZEOF_SHORT + Unsafe.ARRAY_SHORT_BASE_OFFSET;
174
long lengthInBytes = length * SIZEOF_SHORT;
175
unsafe.copyMemory(x, offsetInBytes, null, curAddress, lengthInBytes);
176
position(position() + lengthInBytes);
177
} else {
178
int end = offset + length;
179
for (int i = offset; i < end; i++) {
180
putShort(x[i]);
181
}
182
}
183
return this;
184
}
185
186
/**
187
* putInt() methods...
188
*/
189
190
public final RenderBuffer putInt(int pos, int x) {
191
// assert (baseAddress + pos % SIZEOF_INT == 0);
192
unsafe.putInt(baseAddress + pos, x);
193
return this;
194
}
195
196
public final RenderBuffer putInt(int x) {
197
// assert (position() % SIZEOF_INT == 0);
198
unsafe.putInt(curAddress, x);
199
curAddress += SIZEOF_INT;
200
return this;
201
}
202
203
public RenderBuffer put(int[] x) {
204
return put(x, 0, x.length);
205
}
206
207
public RenderBuffer put(int[] x, int offset, int length) {
208
// assert (position() % SIZEOF_INT == 0);
209
if (length > COPY_FROM_ARRAY_THRESHOLD) {
210
long offsetInBytes = offset * SIZEOF_INT + Unsafe.ARRAY_INT_BASE_OFFSET;
211
long lengthInBytes = length * SIZEOF_INT;
212
unsafe.copyMemory(x, offsetInBytes, null, curAddress, lengthInBytes);
213
position(position() + lengthInBytes);
214
} else {
215
int end = offset + length;
216
for (int i = offset; i < end; i++) {
217
putInt(x[i]);
218
}
219
}
220
return this;
221
}
222
223
/**
224
* putFloat() methods...
225
*/
226
227
public final RenderBuffer putFloat(float x) {
228
// assert (position() % SIZEOF_FLOAT == 0);
229
unsafe.putFloat(curAddress, x);
230
curAddress += SIZEOF_FLOAT;
231
return this;
232
}
233
234
public RenderBuffer put(float[] x) {
235
return put(x, 0, x.length);
236
}
237
238
public RenderBuffer put(float[] x, int offset, int length) {
239
// assert (position() % SIZEOF_FLOAT == 0);
240
if (length > COPY_FROM_ARRAY_THRESHOLD) {
241
long offsetInBytes = offset * SIZEOF_FLOAT + Unsafe.ARRAY_FLOAT_BASE_OFFSET;
242
long lengthInBytes = length * SIZEOF_FLOAT;
243
unsafe.copyMemory(x, offsetInBytes, null, curAddress, lengthInBytes);
244
position(position() + lengthInBytes);
245
} else {
246
int end = offset + length;
247
for (int i = offset; i < end; i++) {
248
putFloat(x[i]);
249
}
250
}
251
return this;
252
}
253
254
/**
255
* putLong() methods...
256
*/
257
258
public final RenderBuffer putLong(long x) {
259
// assert (position() % SIZEOF_LONG == 0);
260
unsafe.putLong(curAddress, x);
261
curAddress += SIZEOF_LONG;
262
return this;
263
}
264
265
public RenderBuffer put(long[] x) {
266
return put(x, 0, x.length);
267
}
268
269
public RenderBuffer put(long[] x, int offset, int length) {
270
// assert (position() % SIZEOF_LONG == 0);
271
if (length > COPY_FROM_ARRAY_THRESHOLD) {
272
long offsetInBytes = offset * SIZEOF_LONG + Unsafe.ARRAY_LONG_BASE_OFFSET;
273
long lengthInBytes = length * SIZEOF_LONG;
274
unsafe.copyMemory(x, offsetInBytes, null, curAddress, lengthInBytes);
275
position(position() + lengthInBytes);
276
} else {
277
int end = offset + length;
278
for (int i = offset; i < end; i++) {
279
putLong(x[i]);
280
}
281
}
282
return this;
283
}
284
285
/**
286
* putDouble() method(s)...
287
*/
288
289
public final RenderBuffer putDouble(double x) {
290
// assert (position() % SIZEOF_DOUBLE == 0);
291
unsafe.putDouble(curAddress, x);
292
curAddress += SIZEOF_DOUBLE;
293
return this;
294
}
295
}
296
297