Beatmup Java package
Context.java
1 /*
2  Beatmup image and signal processing library
3  Copyright (C) 2019, lnstadrum
4 
5  This program is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 package Beatmup;
20 
21 import java.util.HashMap;
22 
23 import Beatmup.Exceptions.CoreException;
24 import Beatmup.Geometry.IntPoint;
25 import Beatmup.Imaging.Color;
26 import Beatmup.Imaging.FloatColor;
27 import Beatmup.Imaging.PixelFormat;
28 
29 
30 /**
31  * Beatmup engine context.
32  * Handles necessary data to interact with the engine through JNI layer
33  */
34 public class Context extends Object {
35  static {
36  System.loadLibrary("c++_shared");
37  System.loadLibrary("beatmup");
38  }
39 
40  private final HashMap<Long, Bitmap> bitmaps;
41 
42  private long eventListenerHandle;
43 
44  // native methods
45  private static native long attachEventListener(long ctx);
46  private static native void detachEventListener(long eventListenerHandle);
47  private static native long getTotalRam();
48 
49  private native float performTask(long ctx, int poolIndex, Task task) throws CoreException;
50  private native int submitTask(long ctx, int poolIndex, Task task);
51  private native int submitPersistentTask(long ctx, int poolIndex, Task task);
52  private native void repeatTask(long ctx, int poolIndex, Task task, boolean abortCurrent);
53  private native void waitForJob(long ctx, int poolIndex, int job);
54  private native boolean abortJob(long ctx, int poolIndex, int job);
55  private native void waitForAllJobs(long ctx, int poolIndex);
56  private native boolean busy(long ctx, int poolIndex);
57  private native void check(long ctx, int poolIndex) throws CoreException;
58 
59  private native long renderChessboard(long ctx, int width, int height, int cellSize, int pixelFormat);
60  private native long copyBitmap(Bitmap bitmap, int newPixelFormat);
61  private native IntPoint scanlineSearchInt(long bitmap, int startX, int startY, int r, int g, int b, int a);
62  private native IntPoint scanlineSearchFloat(long bitmap, int startX, int startY, float r, float g, float b, float a);
63 
64  private native int maxAllowedWorkerCount(long ctx, int poolIndex);
65  private native void limitWorkerCount(long ctx, int poolIndex, int count);
66 
67  private native boolean isGPUQueried(long ctx);
68  private native boolean isGPUReady(long ctx);
69  private native void recycleGPUGarbage(long ctx);
70 
71 
72  /**
73  * Performs a given task in the main thread pool.
74  * @param task The task to run
75  * @return execution time in ms.
76  * @throws CoreException if the main thread pool has unprocessed exceptions thrown by previously executed tasks.
77  */
78  public float performTask(Task task) throws CoreException {
79  return performTask(handle, 0, task);
80  }
81 
82 
83  /**
84  * Performs a given task.
85  * @param task The task to run
86  * @param poolIndex Zero-based index of the thread pool to run the task in.
87  * @return execution time in ms.
88  * @throws CoreException if the thread pool has unprocessed exceptions thrown by previously executed tasks.
89  */
90  public float performTask(Task task, int poolIndex) throws CoreException {
91  return performTask(handle, poolIndex, task);
92  }
93 
94 
95  /**
96  * Ensures a given task executed at least once.
97  * @param task the task
98  * @param abortCurrent if `true` and a task is running, the abort signal is sent.
99  */
100  public void repeatTask(Task task, boolean abortCurrent) {
101  repeatTask(handle, 0, task, abortCurrent);
102  }
103 
104 
105  /**
106  * Ensures a given task executed at least once in a specific thread pool.
107  * @param task The task
108  * @param abortCurrent if `true` and a task is running, the abort signal is sent.
109  * @param poolIndex Index of the thread pool to run the task in
110  */
111  public void repeatTask(Task task, boolean abortCurrent, int poolIndex) {
112  repeatTask(handle, poolIndex, task, abortCurrent);
113  }
114 
115 
116  /**
117  * Submits a persistent task in the main thread pool.
118  * @param task The task
119  * @return job index
120  */
121  public int submitPersistentTask(Task task) {
122  return submitPersistentTask(handle, 0, task);
123  }
124 
125 
126  /**
127  * Submits a persistent task in a specified thread pool.
128  * @param task The task
129  * @param poolIndex Thread pool index
130  * @return job index
131  */
132  public int submitPersistentTask(Task task, int poolIndex) {
133  return submitPersistentTask(handle, poolIndex, task);
134  }
135 
136 
137  /**
138  * Blocks until a given job in the main thread pool finishes.
139  * @param job The job
140  */
141  public void waitForJob(int job) {
142  waitForJob(handle, 0, job);
143  }
144 
145 
146  /**
147  * Blocks until a given job in the main thread pool finishes.
148  * @param job The job
149  * @param poolIndex Thread pool index
150  */
151  public void waitForJob(int job, int poolIndex) {
152  waitForJob(handle, poolIndex, job);
153  }
154 
155 
156  /**
157  * Aborts a given submitted job.
158  * @param job The job
159  * @return `true` if the job was interrupted while running.
160  */
161  public boolean abortJob(int job) {
162  return abortJob(handle, 0, job);
163  }
164 
165 
166  /**
167  * Aborts a given submitted job.
168  * @param job The job
169  * @param poolIndex Thread pool index
170  * @return `true` if the job was interrupted while running.
171  */
172  public boolean abortJob(int job, int poolIndex) {
173  return abortJob(handle, poolIndex, job);
174  }
175 
176 
177  /**
178  * Sets maximum number of threads executing tasks in the main thread pool.
179  * @param newCount the new thread count limit
180  */
181  public void limitWorkerCount(int newCount) {
182  limitWorkerCount(handle, 0, newCount);
183  }
184 
185 
186  /**
187  * Sets maximum number of threads executing tasks in a given thread pool.
188  * @param newCount the new thread count limit
189  * @param poolIndex index of the thread pool
190  */
191  public void limitWorkerCount(int newCount, int poolIndex) {
192  limitWorkerCount(handle, poolIndex, newCount);
193  }
194 
195 
196  /**
197  * Checks if the main thread pool is doing great: rethrows exceptions occurred during tasks execution, if any.
198  * If no exception is thrown, the thread pool is okay.
199  * @throws CoreException occurred while running a task.
200  */
201  public void check() throws CoreException {
202  check(handle, 0);
203  }
204 
205 
206  /**
207  * Checks if a specific thread pool is doing great: rethrows exceptions occurred during tasks execution, if any.
208  * If no exception is thrown, the thread pool is okay.
209  * @param poolIndex The thread pool index
210  * @throws CoreException occurred while running a task.
211  */
212  public void check(int poolIndex) throws CoreException {
213  check(handle, poolIndex);
214  }
215 
216  /**
217  * Creates a new context.
218  */
219  protected Context(long handle) {
220  super(handle);
221  eventListenerHandle = attachEventListener(handle);
222  bitmaps = new HashMap<>();
223  }
224 
225 
226  /**
227  * Adds a bitmap to the watch list
228  * @param bitmap the new bitmap
229  */
230  protected void watchBitmap(Bitmap bitmap) {
231  synchronized (bitmaps) {
232  bitmaps.put(bitmap.handle, bitmap);
233  }
234  }
235 
236 
237  /**
238  * Removes a bitmap from the watch list
239  * @param bitmap the bitmap to remove
240  */
241  protected synchronized void unwatchBitmap(Bitmap bitmap) {
242  synchronized (bitmaps) {
243  bitmaps.remove(bitmap.handle);
244  }
245  }
246 
247 
248  @Override
249  public synchronized void dispose() {
250  synchronized (bitmaps) {
251  for (Bitmap bitmap : bitmaps.values()) {
252  bitmap.dispose();
253  }
254  }
256  super.dispose();
257  detachEventListener(eventListenerHandle);
258  }
259 
260 
261  /**
262  * Renders a chessboard-like image.
263  * @param width output image width in pixels
264  * @param height output image height in pixels
265  * @param cellSize chessboard cell size size in pixels
266  * @param pixelFormat output image pixel format
267  * @return image of chessboard with cells aligned with topleft corner
268  */
269  public Bitmap renderChessboard(int width, int height, int cellSize, PixelFormat pixelFormat) {
270  return new Bitmap(
271  this,
272  renderChessboard(handle, width, height, cellSize, pixelFormat.ordinal())
273  );
274  }
275 
276 
277  /**
278  * Creates a copy of given bitmap.
279  * @param source the bitmap
280  * @param pixelFormat pixel format of the copy
281  * @return copy of the bitmap in the given pixel format
282  */
283  public Bitmap copyBitmap(Bitmap source, PixelFormat pixelFormat) {
284  return new Bitmap(this, copyBitmap(source, pixelFormat.ordinal()));
285  }
286 
287 
288  /**
289  * Goes through a bitmap in scanline order (left to right, top to bottom) until a pixel of a given color is met.
290  * @param bitmap the bitmap to scan
291  * @param color the color value to look for
292  * @param start starting pixel position
293  * @return pixel position coming after the starting point in the scaline order, or {@link #SCANLINE_SEARCH_NOT_FOUND} if no such pixel found till the end (right-bottom bitmap
294  * corner).
295  */
296  public IntPoint scanlineSearch(Bitmap bitmap, Color color, IntPoint start) {
297  return scanlineSearchInt(bitmap.handle, start.x, start.y, color.r, color.g, color.b, color.a);
298  }
299 
300  public IntPoint scanlineSearch(Bitmap source, FloatColor color, IntPoint start) {
301  return scanlineSearchFloat(source.handle, start.x, start.y, color.r, color.g, color.b, color.a);
302  }
303 
304 
305  /**
306  * Tests whether the GPU was already queried.
307  * @return `true` if the GPU was queried
308  */
309  public boolean isGPUQueried() {
310  return isGPUQueried(handle);
311  }
312 
313 
314  /**
315  * Tests whether the GPU was already queried and successfully initialized
316  * @return `true` if yes
317  */
318  public boolean isGPUReady() {
319  return isGPUReady(handle);
320  }
321 
322 
323  /**
324  * Recycles GPU-managed resources that are ready to be disposed in a separate task
325  */
326  public void recycleGPUGarbage() {
328  }
329 
330 
331  /**
332  * @return total size of RAM in bytes
333  */
334  public static long getTotalRAMBytes() {
335  return getTotalRam();
336  }
337 
338  /**
339  * Returned by {@link Beatmup.Context.scanlineSearch()} if no pixel of a specific color is found in the image.
340  */
341  public static final IntPoint SCANLINE_SEARCH_NOT_FOUND = new IntPoint(-1, -1);
342 }
Bitmap wrapper.
Definition: Bitmap.java:32
Beatmup engine context.
Definition: Context.java:34
boolean isGPUReady()
Tests whether the GPU was already queried and successfully initialized.
Definition: Context.java:318
int submitPersistentTask(Task task, int poolIndex)
Submits a persistent task in a specified thread pool.
Definition: Context.java:132
void repeatTask(Task task, boolean abortCurrent)
Ensures a given task executed at least once.
Definition: Context.java:100
void check()
Checks if the main thread pool is doing great: rethrows exceptions occurred during tasks execution,...
Definition: Context.java:201
Bitmap copyBitmap(Bitmap source, PixelFormat pixelFormat)
Creates a copy of given bitmap.
Definition: Context.java:283
Bitmap renderChessboard(int width, int height, int cellSize, PixelFormat pixelFormat)
Renders a chessboard-like image.
Definition: Context.java:269
void watchBitmap(Bitmap bitmap)
Adds a bitmap to the watch list.
Definition: Context.java:230
boolean abortJob(int job, int poolIndex)
Aborts a given submitted job.
Definition: Context.java:172
void limitWorkerCount(int newCount, int poolIndex)
Sets maximum number of threads executing tasks in a given thread pool.
Definition: Context.java:191
void repeatTask(Task task, boolean abortCurrent, int poolIndex)
Ensures a given task executed at least once in a specific thread pool.
Definition: Context.java:111
float performTask(Task task)
Performs a given task in the main thread pool.
Definition: Context.java:78
synchronized void dispose()
Destroys the native object.
Definition: Context.java:249
void limitWorkerCount(int newCount)
Sets maximum number of threads executing tasks in the main thread pool.
Definition: Context.java:181
void waitForJob(int job)
Blocks until a given job in the main thread pool finishes.
Definition: Context.java:141
IntPoint scanlineSearch(Bitmap bitmap, Color color, IntPoint start)
Goes through a bitmap in scanline order (left to right, top to bottom) until a pixel of a given color...
Definition: Context.java:296
boolean isGPUQueried()
Tests whether the GPU was already queried.
Definition: Context.java:309
int submitPersistentTask(Task task)
Submits a persistent task in the main thread pool.
Definition: Context.java:121
float performTask(Task task, int poolIndex)
Performs a given task.
Definition: Context.java:90
void waitForJob(int job, int poolIndex)
Blocks until a given job in the main thread pool finishes.
Definition: Context.java:151
void check(int poolIndex)
Checks if a specific thread pool is doing great: rethrows exceptions occurred during tasks execution,...
Definition: Context.java:212
Context(long handle)
Creates a new context.
Definition: Context.java:219
static final IntPoint SCANLINE_SEARCH_NOT_FOUND
Returned by Beatmup.Context.scanlineSearch() if no pixel of a specific color is found in the image.
Definition: Context.java:341
synchronized void unwatchBitmap(Bitmap bitmap)
Removes a bitmap from the watch list.
Definition: Context.java:241
static long getTotalRAMBytes()
Definition: Context.java:334
void recycleGPUGarbage()
Recycles GPU-managed resources that are ready to be disposed in a separate task.
Definition: Context.java:326
boolean abortJob(int job)
Aborts a given submitted job.
Definition: Context.java:161
Exception occurred in the engine.
Integer-valued 2D point.
Definition: IntPoint.java:24
Integer RGBA color value.
Definition: Color.java:24
Floating-point RGBA color value.
Definition: FloatColor.java:24
Base class for objects natively managed by Beatmup.
Definition: Object.java:24
long handle
pointer to the native object
Definition: Object.java:25
synchronized void dispose()
Destroys the native object.
Definition: Object.java:37
Abstract task.
Definition: Task.java:26
Enumeration of Beatmup pixel formats.