11package bwapi ;
22
3- import com .sun .jna .Platform ;
4- import sun .nio .ch .DirectBuffer ;
5- import java .nio .ByteBuffer ;
3+ import sun .misc .Unsafe ;
4+
65import java .util .ArrayList ;
76import java .util .concurrent .locks .Condition ;
87import java .util .concurrent .locks .Lock ;
1312 */
1413class FrameBuffer {
1514 private static final int BUFFER_SIZE = ClientData .GameData .SIZE ;
15+ private static final Unsafe unsafe = UnsafeTools .getUnsafe ();
1616
1717 private WrappedBuffer liveData ;
1818 private PerformanceMetrics performanceMetrics ;
@@ -158,24 +158,11 @@ void dequeue() {
158158 * @param source Address to copy from
159159 * @param destination Address to copy to
160160 * @param size Number of bytes to copy
161- * @return True if the copy succeeded
162161 */
163- private boolean tryMemcpyBuffer (WrappedBuffer source , WrappedBuffer destination , long offset , int size ) {
162+ private void copyBuffer (WrappedBuffer source , WrappedBuffer destination , long offset , int size ) {
164163 long addressSource = source .getAddress () + offset ;
165164 long addressDestination = destination .getAddress () + offset ;
166- try {
167- if (Platform .isWindows ()) {
168- if (Platform .is64Bit ()) {
169- MSVCRT .INSTANCE .memcpy (addressDestination , addressSource , size );
170- return true ;
171- } else {
172- MSVCRT .INSTANCE .memcpy ((int ) addressDestination , (int ) addressSource , size );
173- return true ;
174- }
175- }
176- }
177- catch (Exception ignored ) {}
178- return false ;
165+ unsafe .copyMemory (addressSource , addressDestination , size );
179166 }
180167
181168 void copyBuffer (WrappedBuffer source , WrappedBuffer destination , boolean copyEverything ) {
@@ -185,16 +172,10 @@ void copyBuffer(WrappedBuffer source, WrappedBuffer destination, boolean copyEve
185172 but are prone to large amounts of variance.
186173
187174 The normal Java way to execute this copy is via ByteBuffer.put(), which has reasonably good performance characteristics.
188- Experiments in 64-bit JRE have shown that using a native memcpy achieves a 35% speedup.
189- Experiments in 32-bit JRE show no difference in performance.
190-
191- So, speculatively, we attempt to do a native memcpy.
192175 */
193176
194177 if (copyEverything ) {
195- if (tryMemcpyBuffer (source , destination , 0 , FrameBuffer .BUFFER_SIZE )) {
196- return ;
197- }
178+ copyBuffer (source , destination , 0 , FrameBuffer .BUFFER_SIZE );
198179 } else {
199180 // After the buffer has been filled the first time,
200181 // we can omit copying blocks of data which are unused or which don't change after game start.
@@ -207,18 +188,10 @@ void copyBuffer(WrappedBuffer source, WrappedBuffer destination, boolean copyEve
207188 final int STRINGSSHAPES_START = 10962632 ; // getStringCount, ... getShapes
208189 final int STRINGSHAPES_END = 32242636 ;
209190 final int UNITFINDER_START = 32962644 ;
210- if (
211- tryMemcpyBuffer (source , destination , 0 , STATICTILES_START )
212- && tryMemcpyBuffer (source , destination , STATICTILES_END , REGION_START - STATICTILES_END )
213- && tryMemcpyBuffer (source , destination , REGION_END , STRINGSSHAPES_START - REGION_END )
214- && tryMemcpyBuffer (source , destination , STRINGSHAPES_END , UNITFINDER_START - STRINGSHAPES_END )) {
215- return ;
216- }
191+ copyBuffer (source , destination , 0 , STATICTILES_START );
192+ copyBuffer (source , destination , STATICTILES_END , REGION_START - STATICTILES_END );
193+ copyBuffer (source , destination , REGION_END , STRINGSSHAPES_START - REGION_END );
194+ copyBuffer (source , destination , STRINGSHAPES_END , UNITFINDER_START - STRINGSHAPES_END );
217195 }
218-
219- // There's no specific case where we expect to fail above,
220- // but this is a safe fallback regardless,
221- // and serves to document the known-good (and cross-platform, for BWAPI 5) way to executing the copy.
222- destination .copyFrom (source );
223196 }
224197}
0 commit comments