1 /*
2  * Copyright (c) 2002-2010 LWJGL Project
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  *   notice, this list of conditions and the following disclaimer.
11  *
12  * * Redistributions in binary form must reproduce the above copyright
13  *   notice, this list of conditions and the following disclaimer in the
14  *   documentation and/or other materials provided with the distribution.
15  *
16  * * Neither the name of 'LWJGL' nor the names of
17  *   its contributors may be used to endorse or promote products derived
18  *   from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 package org.lwjgl.opencl;
33 
34 import org.lwjgl.LWJGLException;
35 import org.lwjgl.opencl.api.CLImageFormat;
36 import org.lwjgl.opencl.api.Filter;
37 import org.lwjgl.opengl.Drawable;
38 
39 import java.nio.IntBuffer;
40 import java.util.List;
41 
42 /**
43  * This class is a wrapper around a cl_context pointer.
44  *
45  * @author Spasi
46  */
47 public final class CLContext extends CLObjectChild<CLPlatform> {
48 
49 	private static final CLContextUtil util = (CLContextUtil)CLPlatform.getInfoUtilInstance(CLContext.class, "CL_CONTEXT_UTIL");
50 
51 	private final CLObjectRegistry<CLCommandQueue> clCommandQueues;
52 	private final CLObjectRegistry<CLMem>          clMems;
53 	private final CLObjectRegistry<CLSampler>      clSamplers;
54 	private final CLObjectRegistry<CLProgram>      clPrograms;
55 	private final CLObjectRegistry<CLEvent>        clEvents;
56 
57 	private long
58 		contextCallback,
59 		printfCallback;
60 
CLContext(final long pointer, final CLPlatform platform)61 	CLContext(final long pointer, final CLPlatform platform) {
62 		super(pointer, platform);
63 
64 		// We do not need to register the context with the platform,
65 		// there is no API that returns cl_context, except clCreateContext.
66 
67 		if ( isValid() ) {
68 			clCommandQueues = new CLObjectRegistry<CLCommandQueue>();
69 			clMems = new CLObjectRegistry<CLMem>();
70 			clSamplers = new CLObjectRegistry<CLSampler>();
71 			clPrograms = new CLObjectRegistry<CLProgram>();
72 			clEvents = new CLObjectRegistry<CLEvent>();
73 		} else {
74 			clCommandQueues = null;
75 			clMems = null;
76 			clSamplers = null;
77 			clPrograms = null;
78 			clEvents = null;
79 		}
80 	}
81 
82 	/**
83 	 * Returns a CLCommandQueue associated with this context.
84 	 *
85 	 * @param id the command queue object id
86 	 *
87 	 * @return the CLCommandQueue object
88 	 */
getCLCommandQueue(final long id)89 	public CLCommandQueue getCLCommandQueue(final long id) { return clCommandQueues.getObject(id); }
90 
91 	/**
92 	 * Returns a CLMem associated with this context.
93 	 *
94 	 * @param id the memory object id
95 	 *
96 	 * @return the CLMem object
97 	 */
getCLMem(final long id)98 	public CLMem getCLMem(final long id) { return clMems.getObject(id); }
99 
100 	/**
101 	 * Returns a CLSampler associated with this context.
102 	 *
103 	 * @param id the sampler object id
104 	 *
105 	 * @return the CLSampler object
106 	 */
getCLSampler(final long id)107 	public CLSampler getCLSampler(final long id) { return clSamplers.getObject(id); }
108 
109 	/**
110 	 * Returns a CLProgram associated with this context.
111 	 *
112 	 * @param id the program object id
113 	 *
114 	 * @return the CLProgram object
115 	 */
getCLProgram(final long id)116 	public CLProgram getCLProgram(final long id) { return clPrograms.getObject(id); }
117 
118 	/**
119 	 * Returns a user CLEvent associated with this context.
120 	 *
121 	 * @param id the event object id
122 	 *
123 	 * @return the CLEvent object
124 	 */
getCLEvent(final long id)125 	public CLEvent getCLEvent(final long id) { return clEvents.getObject(id); }
126 
127 	// ---------------[ UTILITY METHODS ]---------------
128 
129 	/**
130 	 * Creates a new CLContext.
131 	 *
132 	 * @param platform    the platform to use
133 	 * @param devices     the devices to use
134 	 * @param errcode_ret the error code result
135 	 *
136 	 * @return the new CLContext
137 	 *
138 	 * @throws LWJGLException if an exception occurs while creating the context
139 	 */
create(final CLPlatform platform, final List<CLDevice> devices, final IntBuffer errcode_ret)140 	public static CLContext create(final CLPlatform platform, final List<CLDevice> devices, final IntBuffer errcode_ret) throws LWJGLException {
141 		return create(platform, devices, null, null, errcode_ret);
142 	}
143 
144 	/**
145 	 * Creates a new CLContext.
146 	 *
147 	 * @param platform    the platform to use
148 	 * @param devices     the devices to use
149 	 * @param pfn_notify  the context callback function
150 	 * @param errcode_ret the error code result
151 	 *
152 	 * @return the new CLContext
153 	 *
154 	 * @throws LWJGLException if an exception occurs while creating the context
155 	 */
create(final CLPlatform platform, final List<CLDevice> devices, final CLContextCallback pfn_notify, final IntBuffer errcode_ret)156 	public static CLContext create(final CLPlatform platform, final List<CLDevice> devices, final CLContextCallback pfn_notify, final IntBuffer errcode_ret) throws LWJGLException {
157 		return create(platform, devices, pfn_notify, null, errcode_ret);
158 	}
159 
160 	/**
161 	 * Creates a new CLContext.
162 	 *
163 	 * @param platform       the platform to use
164 	 * @param devices        the devices to use
165 	 * @param share_drawable the OpenGL drawable to share objects with
166 	 * @param errcode_ret    the error code result
167 	 *
168 	 * @return the new CLContext
169 	 *
170 	 * @throws LWJGLException if an exception occurs while creating the context
171 	 */
create(final CLPlatform platform, final List<CLDevice> devices, final CLContextCallback pfn_notify, final Drawable share_drawable, final IntBuffer errcode_ret)172 	public static CLContext create(final CLPlatform platform, final List<CLDevice> devices, final CLContextCallback pfn_notify, final Drawable share_drawable, final IntBuffer errcode_ret) throws LWJGLException {
173 		return util.create(platform, devices, pfn_notify, share_drawable, errcode_ret);
174 	}
175 
176 	/**
177 	 * Creates a new CLContext.
178 	 *
179 	 * @param platform    the platform to use
180 	 * @param device_type the device type to use
181 	 * @param errcode_ret the error code result
182 	 *
183 	 * @return the new CLContext
184 	 *
185 	 * @throws LWJGLException if an exception occurs while creating the context
186 	 */
createFromType(final CLPlatform platform, final long device_type, final IntBuffer errcode_ret)187 	public static CLContext createFromType(final CLPlatform platform, final long device_type, final IntBuffer errcode_ret) throws LWJGLException {
188 		return util.createFromType(platform, device_type, null, null, errcode_ret);
189 	}
190 
191 	/**
192 	 * Creates a new CLContext.
193 	 *
194 	 * @param platform    the platform to use
195 	 * @param device_type the device type to use
196 	 * @param pfn_notify  the context callback function
197 	 * @param errcode_ret the error code result
198 	 *
199 	 * @return the new CLContext
200 	 *
201 	 * @throws LWJGLException if an exception occurs while creating the context
202 	 */
createFromType(final CLPlatform platform, final long device_type, final CLContextCallback pfn_notify, final IntBuffer errcode_ret)203 	public static CLContext createFromType(final CLPlatform platform, final long device_type, final CLContextCallback pfn_notify, final IntBuffer errcode_ret) throws LWJGLException {
204 		return util.createFromType(platform, device_type, pfn_notify, null, errcode_ret);
205 	}
206 
207 	/**
208 	 * Creates a new CLContext.
209 	 *
210 	 * @param platform       the platform to use
211 	 * @param device_type    the device type to use
212 	 * @param share_drawable the OpenGL drawable to share objects with
213 	 * @param errcode_ret    the error code result
214 	 *
215 	 * @return the new CLContext
216 	 *
217 	 * @throws LWJGLException if an exception occurs while creating the context
218 	 */
createFromType(final CLPlatform platform, final long device_type, final CLContextCallback pfn_notify, final Drawable share_drawable, final IntBuffer errcode_ret)219 	public static CLContext createFromType(final CLPlatform platform, final long device_type, final CLContextCallback pfn_notify, final Drawable share_drawable, final IntBuffer errcode_ret) throws LWJGLException {
220 		return util.createFromType(platform, device_type, pfn_notify, share_drawable, errcode_ret);
221 	}
222 
223 	/**
224 	 * Returns the integer value of the specified parameter.
225 	 *
226 	 * @param param_name the parameter
227 	 *
228 	 * @return the parameter value
229 	 */
getInfoInt(int param_name)230 	public int getInfoInt(int param_name) {
231 		return util.getInfoInt(this, param_name);
232 	}
233 
234 	/**
235 	 * Returns the list of devices in context.
236 	 *
237 	 * @return the list of devices
238 	 */
getInfoDevices()239 	public List<CLDevice> getInfoDevices() {
240 		return util.getInfoDevices(this);
241 	}
242 
getSupportedImageFormats(final long flags, final int image_type)243 	public List<CLImageFormat> getSupportedImageFormats(final long flags, final int image_type) {
244 		return getSupportedImageFormats(flags, image_type, null);
245 	}
246 
getSupportedImageFormats(final long flags, final int image_type, final Filter<CLImageFormat> filter)247 	public List<CLImageFormat> getSupportedImageFormats(final long flags, final int image_type, final Filter<CLImageFormat> filter) {
248 		return util.getSupportedImageFormats(this, flags, image_type, filter);
249 	}
250 
251 	/** CLContext utility methods interface. */
252 	interface CLContextUtil extends InfoUtil<CLContext> {
253 
getInfoDevices(CLContext context)254 		List<CLDevice> getInfoDevices(CLContext context);
255 
create(CLPlatform platform, List<CLDevice> devices, CLContextCallback pfn_notify, Drawable share_drawable, IntBuffer errcode_ret)256 		CLContext create(CLPlatform platform, List<CLDevice> devices, CLContextCallback pfn_notify, Drawable share_drawable, IntBuffer errcode_ret) throws LWJGLException;
257 
createFromType(CLPlatform platform, long device_type, CLContextCallback pfn_notify, Drawable share_drawable, IntBuffer errcode_ret)258 		CLContext createFromType(CLPlatform platform, long device_type, CLContextCallback pfn_notify, Drawable share_drawable, IntBuffer errcode_ret) throws LWJGLException;
259 
getSupportedImageFormats(CLContext context, final long flags, final int image_type, Filter<CLImageFormat> filter)260 		List<CLImageFormat> getSupportedImageFormats(CLContext context, final long flags, final int image_type, Filter<CLImageFormat> filter);
261 
262 	}
263 
264 	// -------[ IMPLEMENTATION STUFF BELOW ]-------
265 
getCLCommandQueueRegistry()266 	CLObjectRegistry<CLCommandQueue> getCLCommandQueueRegistry() { return clCommandQueues; }
267 
getCLMemRegistry()268 	CLObjectRegistry<CLMem> getCLMemRegistry() { return clMems; }
269 
getCLSamplerRegistry()270 	CLObjectRegistry<CLSampler> getCLSamplerRegistry() { return clSamplers; }
271 
getCLProgramRegistry()272 	CLObjectRegistry<CLProgram> getCLProgramRegistry() { return clPrograms; }
273 
getCLEventRegistry()274 	CLObjectRegistry<CLEvent> getCLEventRegistry() { return clEvents; }
275 
checkCallback(final long callback, final int result)276 	private boolean checkCallback(final long callback, final int result) {
277 		if ( result == 0 && (callback == 0 || isValid()) )
278 			return true;
279 
280 		if ( callback != 0 )
281 			CallbackUtil.deleteGlobalRef(callback);
282 		return false;
283 	}
284 
285 	/**
286 	 * Associates this context with the specified context callback reference. If the context
287 	 * is invalid, the callback reference is deleted. NO-OP if user_data is 0.
288 	 *
289 	 * @param callback the context callback pointer
290 	 */
setContextCallback(final long callback)291 	void setContextCallback(final long callback) {
292 		if ( checkCallback(callback, 0) )
293 			this.contextCallback = callback;
294 	}
295 
296 	/**
297 	 * Associates this context with the specified printf callback reference. If the context
298 	 * is invalid, the callback reference is deleted. NO-OP if user_data is 0.
299 	 *
300 	 * @param callback the printf callback pointer
301 	 */
setPrintfCallback(final long callback, final int result)302 	void setPrintfCallback(final long callback, final int result) {
303 		if ( checkCallback(callback, result) )
304 			this.printfCallback = callback;
305 	}
306 
307 	/**
308 	 * Decrements the context's reference count. If the reference
309 	 * count hits zero, it also deletes
310 	 * any callback objects associated with it.
311 	 */
releaseImpl()312 	void releaseImpl() {
313 		if ( release() > 0 )
314 			return;
315 
316 		if ( contextCallback != 0 )
317 			CallbackUtil.deleteGlobalRef(contextCallback);
318 		if ( printfCallback != 0 )
319 			CallbackUtil.deleteGlobalRef(printfCallback);
320 	}
321 
322 }