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 #import "CGLGraphicsConfig.h"
27 #import "CGLLayer.h"
28 #import "ThreadUtilities.h"
29 #import "LWCToolkit.h"
30 #import "CGLSurfaceData.h"
31
32
33 extern NSOpenGLPixelFormat *sharedPixelFormat;
34 extern NSOpenGLContext *sharedContext;
35
36 @implementation CGLLayer
37
38 @synthesize javaLayer;
39 @synthesize textureID;
40 @synthesize target;
41 @synthesize textureWidth;
42 @synthesize textureHeight;
43 #ifdef REMOTELAYER
44 @synthesize parentLayer;
45 @synthesize remoteLayer;
46 @synthesize jrsRemoteLayer;
47 #endif
48
49 - (id) initWithJavaLayer:(JNFWeakJObjectWrapper *)layer;
50 {
51 AWT_ASSERT_APPKIT_THREAD;
52 // Initialize ourselves
53 self = [super init];
54 if (self == nil) return self;
55
56 self.javaLayer = layer;
57
58 // NOTE: async=YES means that the layer is re-cached periodically
59 self.asynchronous = FALSE;
60 self.contentsGravity = kCAGravityTopLeft;
61 //Layer backed view
62 //self.needsDisplayOnBoundsChange = YES;
63 //self.autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable;
64
65 //Disable CALayer's default animation
66 NSMutableDictionary * actions = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
67 [NSNull null], @"anchorPoint",
68 [NSNull null], @"bounds",
69 [NSNull null], @"contents",
70 [NSNull null], @"contentsScale",
71 [NSNull null], @"onOrderIn",
72 [NSNull null], @"onOrderOut",
73 [NSNull null], @"position",
74 [NSNull null], @"sublayers",
75 nil];
76 self.actions = actions;
77 [actions release];
78
79 textureID = 0; // texture will be created by rendering pipe
80 target = 0;
81
82 return self;
83 }
84
85 - (void) dealloc {
86 self.javaLayer = nil;
87 [super dealloc];
88 }
89
90 - (CGLPixelFormatObj)copyCGLPixelFormatForDisplayMask:(uint32_t)mask {
91 return CGLRetainPixelFormat(sharedPixelFormat.CGLPixelFormatObj);
92 }
93
94 - (CGLContextObj)copyCGLContextForPixelFormat:(CGLPixelFormatObj)pixelFormat {
95 CGLContextObj contextObj = NULL;
96 CGLCreateContext(pixelFormat, sharedContext.CGLContextObj, &contextObj);
97 return contextObj;
98 }
99
100 // use texture (intermediate buffer) as src and blit it to the layer
101 - (void) blitTexture
102 {
103 if (textureID == 0) {
104 return;
105 }
117 glBegin(GL_QUADS);
118 glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f);
119 glTexCoord2f(swid, 0.0f); glVertex2f( 1.0f, -1.0f);
120 glTexCoord2f(swid, shgt); glVertex2f( 1.0f, 1.0f);
121 glTexCoord2f(0.0f, shgt); glVertex2f(-1.0f, 1.0f);
122 glEnd();
123
124 glBindTexture(target, 0);
125 glDisable(target);
126 }
127
128 -(BOOL)canDrawInCGLContext:(CGLContextObj)glContext pixelFormat:(CGLPixelFormatObj)pixelFormat forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp{
129 return textureID == 0 ? NO : YES;
130 }
131
132 -(void)drawInCGLContext:(CGLContextObj)glContext pixelFormat:(CGLPixelFormatObj)pixelFormat forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp
133 {
134 AWT_ASSERT_APPKIT_THREAD;
135
136 JNIEnv *env = [ThreadUtilities getJNIEnv];
137 static JNF_CLASS_CACHE(jc_JavaLayer, "sun/java2d/opengl/CGLLayer");
138 static JNF_MEMBER_CACHE(jm_drawInCGLContext, jc_JavaLayer, "drawInCGLContext", "()V");
139
140 jobject javaLayerLocalRef = [self.javaLayer jObjectWithEnv:env];
141 if ((*env)->IsSameObject(env, javaLayerLocalRef, NULL)) {
142 return;
143 }
144
145 // Set the current context to the one given to us.
146 CGLSetCurrentContext(glContext);
147
148 // Should clear the whole CALayer, because it can be larger than our texture.
149 glClearColor(0.0, 0.0, 0.0, 0.0);
150 glClear(GL_COLOR_BUFFER_BIT);
151
152 glViewport(0, 0, textureWidth, textureHeight);
153
154 JNFCallVoidMethod(env, javaLayerLocalRef, jm_drawInCGLContext);
155 (*env)->DeleteLocalRef(env, javaLayerLocalRef);
156
157 // Call super to finalize the drawing. By default all it does is call glFlush().
158 [super drawInCGLContext:glContext pixelFormat:pixelFormat forLayerTime:timeInterval displayTime:timeStamp];
159
160 CGLSetCurrentContext(NULL);
161 }
162
163 @end
164
165 /*
166 * Class: sun_java2d_opengl_CGLLayer
167 * Method: nativeCreateLayer
168 * Signature: ()J
169 */
170 JNIEXPORT jlong JNICALL
171 Java_sun_java2d_opengl_CGLLayer_nativeCreateLayer
172 (JNIEnv *env, jobject obj)
173 {
174 __block CGLLayer *layer = nil;
175
176 JNF_COCOA_ENTER(env);
177
178 JNFWeakJObjectWrapper *javaLayer = [JNFWeakJObjectWrapper wrapperWithJObject:obj withEnv:env];
179
180 [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
181 AWT_ASSERT_APPKIT_THREAD;
182
183 layer = [[CGLLayer alloc] initWithJavaLayer: javaLayer];
184 }];
185
186 JNF_COCOA_EXIT(env);
187
188 return ptr_to_jlong(layer);
189 }
190
191 // Must be called under the RQ lock.
192 JNIEXPORT void JNICALL
193 Java_sun_java2d_opengl_CGLLayer_validate
194 (JNIEnv *env, jclass cls, jlong layerPtr, jobject surfaceData)
195 {
196 CGLLayer *layer = OBJC(layerPtr);
197
198 if (surfaceData != NULL) {
199 OGLSDOps *oglsdo = (OGLSDOps*) SurfaceData_GetOps(env, surfaceData);
200 layer.textureID = oglsdo->textureID;
201 layer.target = GL_TEXTURE_2D;
202 layer.textureWidth = oglsdo->width;
203 layer.textureHeight = oglsdo->height;
204 } else {
205 layer.textureID = 0;
206 }
207 }
208
209 // Must be called on the AppKit thread and under the RQ lock.
210 JNIEXPORT void JNICALL
211 Java_sun_java2d_opengl_CGLLayer_blitTexture
212 (JNIEnv *env, jclass cls, jlong layerPtr)
213 {
214 CGLLayer *layer = jlong_to_ptr(layerPtr);
215
216 [layer blitTexture];
217 }
218
219 JNIEXPORT void JNICALL
220 Java_sun_java2d_opengl_CGLLayer_nativeSetScale
221 (JNIEnv *env, jclass cls, jlong layerPtr, jdouble scale)
222 {
223 JNF_COCOA_ENTER(env);
224 CGLLayer *layer = jlong_to_ptr(layerPtr);
225 // We always call all setXX methods asynchronously, exception is only in
226 // this method where we need to change native texture size and layer's scale
227 // in one call on appkit, otherwise we'll get window's contents blinking,
228 // during screen-2-screen moving.
229 [ThreadUtilities performOnMainThreadWaiting:[NSThread isMainThread] block:^(){
230 layer.contentsScale = scale;
231 }];
232 JNF_COCOA_EXIT(env);
233 }
|
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 #import "CGLGraphicsConfig.h"
27 #import "CGLLayer.h"
28 #import "ThreadUtilities.h"
29 #import "LWCToolkit.h"
30 #import "CGLSurfaceData.h"
31 #import "JNIUtilities.h"
32
33
34 extern NSOpenGLPixelFormat *sharedPixelFormat;
35 extern NSOpenGLContext *sharedContext;
36
37 @implementation CGLLayer
38
39 @synthesize javaLayer;
40 @synthesize textureID;
41 @synthesize target;
42 @synthesize textureWidth;
43 @synthesize textureHeight;
44 #ifdef REMOTELAYER
45 @synthesize parentLayer;
46 @synthesize remoteLayer;
47 @synthesize jrsRemoteLayer;
48 #endif
49
50 - (id) initWithJavaLayer:(jobject)layer;
51 {
52 AWT_ASSERT_APPKIT_THREAD;
53 // Initialize ourselves
54 self = [super init];
55 if (self == nil) return self;
56
57 self.javaLayer = layer;
58
59 // NOTE: async=YES means that the layer is re-cached periodically
60 self.asynchronous = FALSE;
61 self.contentsGravity = kCAGravityTopLeft;
62 //Layer backed view
63 //self.needsDisplayOnBoundsChange = YES;
64 //self.autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable;
65
66 //Disable CALayer's default animation
67 NSMutableDictionary * actions = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
68 [NSNull null], @"anchorPoint",
69 [NSNull null], @"bounds",
70 [NSNull null], @"contents",
71 [NSNull null], @"contentsScale",
72 [NSNull null], @"onOrderIn",
73 [NSNull null], @"onOrderOut",
74 [NSNull null], @"position",
75 [NSNull null], @"sublayers",
76 nil];
77 self.actions = actions;
78 [actions release];
79
80 textureID = 0; // texture will be created by rendering pipe
81 target = 0;
82
83 return self;
84 }
85
86 - (void) dealloc {
87 JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
88 (*env)->DeleteWeakGlobalRef(env, self.javaLayer);
89 self.javaLayer = nil;
90 [super dealloc];
91 }
92
93 - (CGLPixelFormatObj)copyCGLPixelFormatForDisplayMask:(uint32_t)mask {
94 return CGLRetainPixelFormat(sharedPixelFormat.CGLPixelFormatObj);
95 }
96
97 - (CGLContextObj)copyCGLContextForPixelFormat:(CGLPixelFormatObj)pixelFormat {
98 CGLContextObj contextObj = NULL;
99 CGLCreateContext(pixelFormat, sharedContext.CGLContextObj, &contextObj);
100 return contextObj;
101 }
102
103 // use texture (intermediate buffer) as src and blit it to the layer
104 - (void) blitTexture
105 {
106 if (textureID == 0) {
107 return;
108 }
120 glBegin(GL_QUADS);
121 glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f);
122 glTexCoord2f(swid, 0.0f); glVertex2f( 1.0f, -1.0f);
123 glTexCoord2f(swid, shgt); glVertex2f( 1.0f, 1.0f);
124 glTexCoord2f(0.0f, shgt); glVertex2f(-1.0f, 1.0f);
125 glEnd();
126
127 glBindTexture(target, 0);
128 glDisable(target);
129 }
130
131 -(BOOL)canDrawInCGLContext:(CGLContextObj)glContext pixelFormat:(CGLPixelFormatObj)pixelFormat forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp{
132 return textureID == 0 ? NO : YES;
133 }
134
135 -(void)drawInCGLContext:(CGLContextObj)glContext pixelFormat:(CGLPixelFormatObj)pixelFormat forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp
136 {
137 AWT_ASSERT_APPKIT_THREAD;
138
139 JNIEnv *env = [ThreadUtilities getJNIEnv];
140 DECLARE_CLASS(jc_JavaLayer, "sun/java2d/opengl/CGLLayer");
141 DECLARE_METHOD(jm_drawInCGLContext, jc_JavaLayer, "drawInCGLContext", "()V");
142
143 jobject javaLayerLocalRef = (*env)->NewLocalRef(env, self.javaLayer);
144 if ((*env)->IsSameObject(env, javaLayerLocalRef, NULL)) {
145 return;
146 }
147
148 // Set the current context to the one given to us.
149 CGLSetCurrentContext(glContext);
150
151 // Should clear the whole CALayer, because it can be larger than our texture.
152 glClearColor(0.0, 0.0, 0.0, 0.0);
153 glClear(GL_COLOR_BUFFER_BIT);
154
155 glViewport(0, 0, textureWidth, textureHeight);
156
157 (*env)->CallVoidMethod(env, javaLayerLocalRef, jm_drawInCGLContext);
158 CHECK_EXCEPTION();
159 (*env)->DeleteLocalRef(env, javaLayerLocalRef);
160
161 // Call super to finalize the drawing. By default all it does is call glFlush().
162 [super drawInCGLContext:glContext pixelFormat:pixelFormat forLayerTime:timeInterval displayTime:timeStamp];
163
164 CGLSetCurrentContext(NULL);
165 }
166
167 @end
168
169 /*
170 * Class: sun_java2d_opengl_CGLLayer
171 * Method: nativeCreateLayer
172 * Signature: ()J
173 */
174 JNIEXPORT jlong JNICALL
175 Java_sun_java2d_opengl_CGLLayer_nativeCreateLayer
176 (JNIEnv *env, jobject obj)
177 {
178 __block CGLLayer *layer = nil;
179
180 JNI_COCOA_ENTER(env);
181
182 jobject javaLayer = (*env)->NewWeakGlobalRef(env, obj);
183
184 [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
185 AWT_ASSERT_APPKIT_THREAD;
186
187 layer = [[CGLLayer alloc] initWithJavaLayer: javaLayer];
188 }];
189
190 JNI_COCOA_EXIT(env);
191
192 return ptr_to_jlong(layer);
193 }
194
195 // Must be called under the RQ lock.
196 JNIEXPORT void JNICALL
197 Java_sun_java2d_opengl_CGLLayer_validate
198 (JNIEnv *env, jclass cls, jlong layerPtr, jobject surfaceData)
199 {
200 CGLLayer *layer = OBJC(layerPtr);
201
202 if (surfaceData != NULL) {
203 OGLSDOps *oglsdo = (OGLSDOps*) SurfaceData_GetOps(env, surfaceData);
204 layer.textureID = oglsdo->textureID;
205 layer.target = GL_TEXTURE_2D;
206 layer.textureWidth = oglsdo->width;
207 layer.textureHeight = oglsdo->height;
208 } else {
209 layer.textureID = 0;
210 }
211 }
212
213 // Must be called on the AppKit thread and under the RQ lock.
214 JNIEXPORT void JNICALL
215 Java_sun_java2d_opengl_CGLLayer_blitTexture
216 (JNIEnv *env, jclass cls, jlong layerPtr)
217 {
218 CGLLayer *layer = jlong_to_ptr(layerPtr);
219
220 [layer blitTexture];
221 }
222
223 JNIEXPORT void JNICALL
224 Java_sun_java2d_opengl_CGLLayer_nativeSetScale
225 (JNIEnv *env, jclass cls, jlong layerPtr, jdouble scale)
226 {
227 JNI_COCOA_ENTER(env);
228 CGLLayer *layer = jlong_to_ptr(layerPtr);
229 // We always call all setXX methods asynchronously, exception is only in
230 // this method where we need to change native texture size and layer's scale
231 // in one call on appkit, otherwise we'll get window's contents blinking,
232 // during screen-2-screen moving.
233 [ThreadUtilities performOnMainThreadWaiting:[NSThread isMainThread] block:^(){
234 layer.contentsScale = scale;
235 }];
236 JNI_COCOA_EXIT(env);
237 }
|