From cab2ad6b4394b8577965d60d48e07f17ee5af2c0 Mon Sep 17 00:00:00 2001 From: Lyubomir Marinov Date: Fri, 25 Mar 2011 08:32:05 +0000 Subject: Fixes overlapping issues with the JAWTRenderer on Mac OS X. --- lib/native/mac/libjawtrenderer.jnilib | Bin 45008 -> 89800 bytes src/native/jawtrenderer/JAWTRenderer_MacOSX.m | 84 ++++++++++----------- .../jmfext/media/renderer/video/JAWTRenderer.java | 84 ++++++++++++++++++++- 3 files changed, 122 insertions(+), 46 deletions(-) diff --git a/lib/native/mac/libjawtrenderer.jnilib b/lib/native/mac/libjawtrenderer.jnilib index f4cc02f..c069b10 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 4464614..0ae6227 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 e944cb1..e481b2a 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 class JAWTRenderer */ 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 @@ public class JAWTRenderer */ 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 class JAWTRenderer } } + /** + * Releases the resources of this NonVideoComponent and + * prepares it to be garbage collected. + */ public void dispose() { if (handle != 0) @@ -721,10 +749,19 @@ public class JAWTRenderer } } + /** + * 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 class JAWTRenderer 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 class JAWTRenderer @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 @@ public class JAWTRenderer 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 class JAWTRenderer @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 @@ public class JAWTRenderer @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) -- cgit v1.1