diff --git a/lib/native/mac/libjawtrenderer.jnilib b/lib/native/mac/libjawtrenderer.jnilib
index f4cc02fb6..c069b10ba 100755
Binary files a/lib/native/mac/libjawtrenderer.jnilib and b/lib/native/mac/libjawtrenderer.jnilib differ
diff --git a/src/native/jawtrenderer/JAWTRenderer_MacOSX.m b/src/native/jawtrenderer/JAWTRenderer_MacOSX.m
index 446461456..0ae6227c2 100644
--- a/src/native/jawtrenderer/JAWTRenderer_MacOSX.m
+++ b/src/native/jawtrenderer/JAWTRenderer_MacOSX.m
@@ -398,7 +398,6 @@ JAWTRenderer_removeNotifyLightweightComponent(jlong handle, jobject component)
}
[self setView:nil];
- [self copyCGLContext:nil forPixelFormat:0];
[super dealloc];
}
@@ -413,9 +412,6 @@ JAWTRenderer_removeNotifyLightweightComponent(jlong handle, jobject component)
{
if ((self = [super init]))
{
- NSOpenGLPixelFormatAttribute pixelFormatAttribs[]
- = { NSOpenGLPFAWindow, 0 };
- NSOpenGLPixelFormat *pixelFormat;
glContext = nil;
@@ -437,52 +433,15 @@ JAWTRenderer_removeNotifyLightweightComponent(jlong handle, jobject component)
subrenderers = nil;
superrenderer = nil;
-
- pixelFormat
- = [[NSOpenGLPixelFormat alloc]
- initWithAttributes:pixelFormatAttribs];
- if (pixelFormat)
- {
- glContext
- = [[NSOpenGLContext alloc]
- initWithFormat:pixelFormat
- shareContext:nil];
- if (glContext)
- {
- GLint surfaceOpacity;
-
- // prepareOpenGL
- [glContext makeCurrentContext];
-
- surfaceOpacity = 1;
- [glContext setValues:&surfaceOpacity
- forParameter:NSOpenGLCPSurfaceOpacity];
-
- glDisable(GL_BLEND);
- glDisable(GL_DEPTH_TEST);
- glDepthMask(GL_FALSE);
- glDisable(GL_CULL_FACE);
- glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT);
- }
- else
- {
- [self release];
- self = nil;
- }
- [pixelFormat release];
- }
- else
- {
- [self release];
- self = nil;
- }
}
return self;
}
- (void)paint
{
+ if (!glContext)
+ return;
+
[glContext makeCurrentContext];
// drawRect:
@@ -676,6 +635,8 @@ JAWTRenderer_removeNotifyLightweightComponent(jlong handle, jobject component)
}
#endif /* JAWT_RENDERER_USE_NSNOTIFICATIONCENTER */
+ [self copyCGLContext:nil forPixelFormat:0];
+
[view release];
}
@@ -683,13 +644,46 @@ JAWTRenderer_removeNotifyLightweightComponent(jlong handle, jobject component)
if (view)
{
+ NSOpenGLPixelFormatAttribute pixelFormatAttribs[]
+ = { NSOpenGLPFAWindow, 0 };
+ NSOpenGLPixelFormat *pixelFormat;
+
#ifdef JAWT_RENDERER_USE_NSNOTIFICATIONCENTER
NSNotificationCenter *notificationCenter;
#endif /* JAWT_RENDERER_USE_NSNOTIFICATIONCENTER */
[view retain];
+
+ pixelFormat
+ = [[NSOpenGLPixelFormat alloc]
+ initWithAttributes:pixelFormatAttribs];
+ if (pixelFormat)
+ {
+ glContext
+ = [[NSOpenGLContext alloc] initWithFormat:pixelFormat
+ shareContext:nil];
+ if (glContext)
+ {
+ GLint surfaceOpacity;
+
+ // prepareOpenGL
+ [glContext makeCurrentContext];
+
+ surfaceOpacity = 1;
+ [glContext setValues:&surfaceOpacity
+ forParameter:NSOpenGLCPSurfaceOpacity];
+
+ glDisable(GL_BLEND);
+ glDisable(GL_DEPTH_TEST);
+ glDepthMask(GL_FALSE);
+ glDisable(GL_CULL_FACE);
+ glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+ }
+ [pixelFormat release];
+ }
- if ([glContext view] != view)
+ if (glContext && ([glContext view] != view))
[glContext setView:view];
#ifdef JAWT_RENDERER_USE_NSNOTIFICATIONCENTER
diff --git a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/renderer/video/JAWTRenderer.java b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/renderer/video/JAWTRenderer.java
index e944cb1fd..e481b2a81 100644
--- a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/renderer/video/JAWTRenderer.java
+++ b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/renderer/video/JAWTRenderer.java
@@ -73,7 +73,7 @@ public class JAWTRenderer
* The indicator which determines whether CALayer-based painting is
* to be performed by JAWTRenderer on Mac OS X.
*/
- private static final boolean USE_MACOSX_CALAYERS = false;
+ private static final boolean USE_MACOSX_CALAYERS = true;
static
{
@@ -668,6 +668,11 @@ public void update(Graphics g)
*/
private static class NonVideoComponent
{
+ /**
+ * The BufferedImage into which {@link #component} is to be
+ * painted so that it can be processed and then rendered by
+ * {@link #handle}.
+ */
private BufferedImage bufferedImage;
/**
@@ -682,12 +687,31 @@ private static class NonVideoComponent
*/
private long handle;
+ /**
+ * The height in pixels of {@link #bufferedImage} and {@link #rgb}.
+ */
private int height;
+ /**
+ * The pixels of {@link #bufferedImage} to be processed by
+ * {@link #handle}.
+ */
private int[] rgb;
+ /**
+ * The width in pixels of {@link #bufferedImage} and {@link #rgb}.
+ */
private int width;
+ /**
+ * Initializes a new NonVideoComponent instance which is to
+ * paint a specific Component in the context of a parent
+ * JAWTRenderer.
+ *
+ * @param component the Component to be painted
+ * @param parentHandle the handle of the native JAWTRenderer in
+ * the context of which component is to be painted
+ */
public NonVideoComponent(Component component, long parentHandle)
{
this.component = component;
@@ -710,6 +734,10 @@ public NonVideoComponent(Component component, long parentHandle)
}
}
+ /**
+ * Releases the resources of this NonVideoComponent and
+ * prepares it to be garbage collected.
+ */
public void dispose()
{
if (handle != 0)
@@ -721,10 +749,19 @@ public void dispose()
}
}
+ /**
+ * Paints the Component associated with this
+ * NonVideoComponent instance.
+ */
public void paint()
{
if (handle != 0)
{
+ /*
+ * Make sure the location, the size and the visibility known to
+ * the associated native JAWTRenderer are in sync with these of
+ * the component.
+ */
Rectangle bounds = component.getBounds();
if (!component.isVisible())
@@ -736,9 +773,17 @@ public void paint()
handle,
bounds.x, bounds.y, bounds.width, bounds.height);
+ /*
+ * If the component is not visible, the native JAWTRenderer
+ * already knows that it is not to be rendered.
+ */
if ((bounds.height < 1) || (bounds.width < 1))
return;
+ /*
+ * Paint the component and tell the native JAWTRenderer about
+ * the latest painting.
+ */
if ((height != bounds.height) || (width != bounds.width))
{
rgb = new int[bounds.width * bounds.height];
@@ -1167,9 +1212,18 @@ public void addNotify()
@Override
public boolean contains(int x, int y)
{
+ /*
+ * Act as a "glass pane" i.e. be transparent with respect to points
+ * and pretend they are in whatever is underneath.
+ */
return false;
}
+ /**
+ * Dispatches MouseEvents to whatever is underneath this
+ * SwingVideoComponentCanvas because it only renders
+ * Components i.e. it is like a "glass pane".
+ */
private boolean dispatchMouseEvent(MouseEvent e)
{
Component srcc = e.getComponent();
@@ -1201,6 +1255,20 @@ private boolean dispatchMouseEvent(MouseEvent e)
return false;
}
+ /**
+ * Determines the Component which is a child of a specific
+ * Container which contains a specific Point. Since
+ * SwingVideoComponentCanvas is like a "glass pane", it never
+ * contains the specified point.
+ *
+ * @param parent the Container which contains the
+ * Components which may contain the specified point
+ * @param point the point in the coordinate system of parent
+ * which is to be determined which Component contains it
+ * @return the Component which is a child of the specified
+ * Container and contains the specified Point or
+ * null if there is no such Component
+ */
private Component getComponentAt(Container parent, Point point)
{
Component[] components = parent.getComponents();
@@ -1313,6 +1381,10 @@ public void paint(Graphics g)
@Override
protected void processMouseEvent(MouseEvent e)
{
+ /*
+ * Act as a "glass pane" i.e. be transparent with respect to
+ * MouseEvents and dispatch them to whatever is underneath.
+ */
if (!dispatchMouseEvent(e))
super.processMouseEvent(e);
}
@@ -1320,10 +1392,20 @@ protected void processMouseEvent(MouseEvent e)
@Override
protected void processMouseMotionEvent(MouseEvent e)
{
+ /*
+ * Act as a "glass pane" i.e. be transparent with respect to
+ * MouseEvents and dispatch them to whatever is underneath.
+ */
if (!dispatchMouseEvent(e))
super.processMouseMotionEvent(e);
}
+ /**
+ * Removes all NonVideoComponents from this
+ * SwingVideoComponentCanvas so that their associated
+ * Components are no longer painted by the reperesented native
+ * JAWTRenderer.
+ */
private void removeAllNonVideoComponents()
{
synchronized (nonVideoComponents)