diff options
author | Silenio Quarti <Silenio_Quarti@ca.ibm.com> | 2011-10-21 13:01:26 -0400 |
---|---|---|
committer | Silenio Quarti <Silenio_Quarti@ca.ibm.com> | 2011-10-21 13:01:26 -0400 |
commit | 5f4db6cac20e7848d08e2ea1bbe5bd403d3937b3 (patch) | |
tree | 24bdab46f5d61d2f12ee90fb1b30f551b63f4f44 | |
parent | bd2766fbbc1833bd27095dbb70acd67cae7b7651 (diff) | |
download | eclipse.platform.swt-5f4db6cac20e7848d08e2ea1bbe5bd403d3937b3.tar.gz eclipse.platform.swt-5f4db6cac20e7848d08e2ea1bbe5bd403d3937b3.tar.xz eclipse.platform.swt-5f4db6cac20e7848d08e2ea1bbe5bd403d3937b3.zip |
support Images with xlib surface, performance of large images surfaces is bad
12 files changed, 125 insertions, 14 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo.c b/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo.c index b6177e34db..cfefce37a6 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo.c +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo.c @@ -1560,6 +1560,26 @@ JNIEXPORT void JNICALL Cairo_NATIVE(_1cairo_1surface_1finish) } #endif +#ifndef NO__1cairo_1surface_1get_1content +JNIEXPORT jint JNICALL Cairo_NATIVE(_1cairo_1surface_1get_1content) + (JNIEnv *env, jclass that, jintLong arg0) +{ + jint rc = 0; + Cairo_NATIVE_ENTER(env, that, _1cairo_1surface_1get_1content_FUNC); +/* + rc = (jint)cairo_surface_get_content((cairo_surface_t *)arg0); +*/ + { + Cairo_LOAD_FUNCTION(fp, cairo_surface_get_content) + if (fp) { + rc = (jint)((jint (CALLING_CONVENTION*)(cairo_surface_t *))fp)((cairo_surface_t *)arg0); + } + } + Cairo_NATIVE_EXIT(env, that, _1cairo_1surface_1get_1content_FUNC); + return rc; +} +#endif + #ifndef NO__1cairo_1surface_1get_1type JNIEXPORT jint JNICALL Cairo_NATIVE(_1cairo_1surface_1get_1type) (JNIEnv *env, jclass that, jintLong arg0) diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_custom.h b/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_custom.h index 741742eeb7..c16af1c283 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_custom.h +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_custom.h @@ -37,4 +37,5 @@ #define cairo_image_surface_get_format_LIB LIB_CAIRO #define cairo_image_surface_get_stride_LIB LIB_CAIRO #define cairo_xlib_surface_get_height_LIB LIB_CAIRO -#define cairo_xlib_surface_get_width_LIB LIB_CAIRO
\ No newline at end of file +#define cairo_xlib_surface_get_width_LIB LIB_CAIRO +#define cairo_surface_get_content_LIB LIB_CAIRO
\ No newline at end of file diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_stats.c b/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_stats.c index 29f02c96b0..ce3627f4a9 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_stats.c +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_stats.c @@ -24,8 +24,8 @@ #ifdef NATIVE_STATS -int Cairo_nativeFunctionCount = 151; -int Cairo_nativeFunctionCallCount[151]; +int Cairo_nativeFunctionCount = 152; +int Cairo_nativeFunctionCallCount[152]; char * Cairo_nativeFunctionNames[] = { "CAIRO_1VERSION_1ENCODE", "_1cairo_1append_1path", @@ -153,6 +153,7 @@ char * Cairo_nativeFunctionNames[] = { "_1cairo_1surface_1create_1similar", "_1cairo_1surface_1destroy", "_1cairo_1surface_1finish", + "_1cairo_1surface_1get_1content", "_1cairo_1surface_1get_1type", "_1cairo_1surface_1get_1user_1data", "_1cairo_1surface_1reference", diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_stats.h b/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_stats.h index ffd20b3cc3..435725ae82 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_stats.h +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_stats.h @@ -161,6 +161,7 @@ typedef enum { _1cairo_1surface_1create_1similar_FUNC, _1cairo_1surface_1destroy_FUNC, _1cairo_1surface_1finish_FUNC, + _1cairo_1surface_1get_1content_FUNC, _1cairo_1surface_1get_1type_FUNC, _1cairo_1surface_1get_1user_1data_FUNC, _1cairo_1surface_1reference_FUNC, diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/org/eclipse/swt/internal/cairo/Cairo.java b/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/org/eclipse/swt/internal/cairo/Cairo.java index 9365caa07a..c52f924977 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/org/eclipse/swt/internal/cairo/Cairo.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/org/eclipse/swt/internal/cairo/Cairo.java @@ -31,7 +31,10 @@ public class Cairo extends Platform { public static final int CAIRO_ANTIALIAS_DEFAULT = 0; public static final int CAIRO_ANTIALIAS_NONE = 1; public static final int CAIRO_ANTIALIAS_GRAY = 2; - public static final int CAIRO_ANTIALIAS_SUBPIXEL = 3; + public static final int CAIRO_ANTIALIAS_SUBPIXEL = 3; + public static final int CAIRO_CONTENT_COLOR = 0x1000; + public static final int CAIRO_CONTENT_ALPHA = 0x2000; + public static final int CAIRO_CONTENT_COLOR_ALPHA = 0x3000; public static final int CAIRO_FORMAT_ARGB32 = 0; public static final int CAIRO_FORMAT_RGB24 = 1; public static final int CAIRO_FORMAT_A8 = 2; @@ -1441,6 +1444,19 @@ public static final int cairo_surface_get_type(int /*long*/ surface) { } } /** + * @method flags=dynamic + * @param surface cast=(cairo_surface_t *) + */ +public static final native int _cairo_surface_get_content(int /*long*/ surface); +public static final int cairo_surface_get_content(int /*long*/ surface) { + lock.lock(); + try { + return _cairo_surface_get_content(surface); + } finally { + lock.unlock(); + } +} +/** * @param surface cast=(cairo_surface_t *) * @param key cast=(cairo_user_data_key_t *) */ diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c index 61bbdce18f..841c036199 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c @@ -6801,6 +6801,26 @@ JNIEXPORT void JNICALL OS_NATIVE(_1gdk_1window_1clear_1area) } #endif +#ifndef NO__1gdk_1window_1create_1similar_1surface +JNIEXPORT jintLong JNICALL OS_NATIVE(_1gdk_1window_1create_1similar_1surface) + (JNIEnv *env, jclass that, jintLong arg0, jint arg1, jint arg2, jint arg3) +{ + jintLong rc = 0; + OS_NATIVE_ENTER(env, that, _1gdk_1window_1create_1similar_1surface_FUNC); +/* + rc = (jintLong)gdk_window_create_similar_surface((GdkWindow *)arg0, arg1, arg2, arg3); +*/ + { + OS_LOAD_FUNCTION(fp, gdk_window_create_similar_surface) + if (fp) { + rc = (jintLong)((jintLong (CALLING_CONVENTION*)(GdkWindow *, jint, jint, jint))fp)((GdkWindow *)arg0, arg1, arg2, arg3); + } + } + OS_NATIVE_EXIT(env, that, _1gdk_1window_1create_1similar_1surface_FUNC); + return rc; +} +#endif + #ifndef NO__1gdk_1window_1destroy JNIEXPORT void JNICALL OS_NATIVE(_1gdk_1window_1destroy) (JNIEnv *env, jclass that, jintLong arg0) diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_custom.h b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_custom.h index daaf74c241..d3bf5c78d2 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_custom.h +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_custom.h @@ -152,6 +152,7 @@ #define gtk_status_icon_position_menu_LIB LIB_GTK #define gtk_window_get_group_LIB LIB_GTK #define gtk_window_get_opacity_LIB LIB_GTK +#define gdk_window_create_similar_surface_LIB LIB_GDK #define gdk_window_restack_LIB LIB_GDK #define gdk_window_set_keep_above_LIB LIB_GDK #define gdk_window_set_accept_focus_LIB LIB_GDK diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c index 2c78396ae2..fc1491b6a8 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c @@ -18,8 +18,8 @@ #ifdef NATIVE_STATS -int OS_nativeFunctionCount = 1397; -int OS_nativeFunctionCallCount[1397]; +int OS_nativeFunctionCount = 1398; +int OS_nativeFunctionCallCount[1398]; char * OS_nativeFunctionNames[] = { #ifndef JNI64 "Call__IIII", @@ -559,6 +559,7 @@ char * OS_nativeFunctionNames[] = { "_1gdk_1window_1at_1pointer", "_1gdk_1window_1begin_1paint_1rect", "_1gdk_1window_1clear_1area", + "_1gdk_1window_1create_1similar_1surface", "_1gdk_1window_1destroy", "_1gdk_1window_1end_1paint", "_1gdk_1window_1focus", diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h index 67de14abc2..656d931f98 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h @@ -567,6 +567,7 @@ typedef enum { _1gdk_1window_1at_1pointer_FUNC, _1gdk_1window_1begin_1paint_1rect_FUNC, _1gdk_1window_1clear_1area_FUNC, + _1gdk_1window_1create_1similar_1surface_FUNC, _1gdk_1window_1destroy_FUNC, _1gdk_1window_1end_1paint_FUNC, _1gdk_1window_1focus_FUNC, diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java index dfe3ce30f6..d13b28e754 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java @@ -5262,6 +5262,19 @@ public static final void gdk_window_clear_area(int /*long*/ window, int x, int y lock.unlock(); } } +/** + * @method flags=dynamic + * @param window cast=(GdkWindow *) + */ +public static final native int /*long*/ _gdk_window_create_similar_surface(int /*long*/ window, int content, int width, int height); +public static final int /*long*/ gdk_window_create_similar_surface(int /*long*/ window, int content, int width, int height) { + lock.lock(); + try { + return _gdk_window_create_similar_surface(window, content, width, height); + } finally { + lock.unlock(); + } +} /** @param window cast=(GdkWindow *) */ public static final native void _gdk_window_destroy(int /*long*/ window); public static final void gdk_window_destroy(int /*long*/ window) { diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java index 1a524e2953..316b09c2e6 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java @@ -256,9 +256,9 @@ public Image(Device device, Image srcImage, int flag) { } int /*long*/ imageSurface = srcImage.surface; - int format = Cairo.cairo_image_surface_get_format(imageSurface); - int width = this.width = Cairo.cairo_image_surface_get_width(imageSurface); - int height = this.height = Cairo.cairo_image_surface_get_height(imageSurface); + int width = this.width = srcImage.width; + int height = this.height = srcImage.height; + int format = Cairo.cairo_surface_get_content(imageSurface) == Cairo.CAIRO_CONTENT_COLOR ? Cairo.CAIRO_FORMAT_RGB24 : Cairo.CAIRO_FORMAT_ARGB32; boolean hasAlpha = format == Cairo.CAIRO_FORMAT_ARGB32; surface = Cairo.cairo_image_surface_create(format, width, height); if (surface == 0) SWT.error(SWT.ERROR_NO_HANDLES); @@ -1089,6 +1089,7 @@ public ImageData getImageData() { if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); ImageData data; if (OS.USE_CAIRO) { + int /*long*/ surface = ImageList.convertSurface(this); int format = Cairo.cairo_image_surface_get_format(surface); int width = Cairo.cairo_image_surface_get_width(surface); int height = Cairo.cairo_image_surface_get_height(surface); @@ -1135,6 +1136,7 @@ public ImageData getImageData() { } } } + Cairo.cairo_surface_destroy(surface); } else { int[] w = new int[1], h = new int[1]; OS.gdk_drawable_get_size(pixmap, w, h); @@ -1265,11 +1267,24 @@ void init(int width, int height) { /* Create the pixmap */ if (OS.USE_CAIRO) { - surface = Cairo.cairo_image_surface_create(Cairo.CAIRO_FORMAT_RGB24, width, height); + if (OS.GTK_VERSION >= OS.VERSION(2, 22, 0)) { + surface = OS.gdk_window_create_similar_surface(OS.GDK_ROOT_PARENT(), Cairo.CAIRO_CONTENT_COLOR, width, height); + } else { + int /*long*/ xDisplay = OS.GDK_DISPLAY(); + int /*long*/ xDrawable = OS.GDK_PIXMAP_XID(OS.GDK_ROOT_PARENT()); + int /*long*/ xVisual = OS.gdk_x11_visual_get_xvisual(OS.gdk_visual_get_system()); + int /*long*/ rootSurface = Cairo.cairo_xlib_surface_create(xDisplay, xDrawable, xVisual, 1, 1); + if (rootSurface == 0) SWT.error(SWT.ERROR_NO_HANDLES); + surface = Cairo.cairo_surface_create_similar(rootSurface, Cairo.CAIRO_CONTENT_COLOR, width, height); + Cairo.cairo_surface_destroy(rootSurface); + } if (surface == 0) SWT.error(SWT.ERROR_NO_HANDLES); - int stride = Cairo.cairo_image_surface_get_stride(surface); - int /*long*/ data = Cairo.cairo_image_surface_get_data(surface); - OS.memset(data, 0xff, stride * height); + int /*long*/ cairo = Cairo.cairo_create(surface); + if (cairo == 0) SWT.error(SWT.ERROR_NO_HANDLES); + Cairo.cairo_set_source_rgb(cairo, 1, 1, 1); + Cairo.cairo_rectangle(cairo, 0, 0, width, height); + Cairo.cairo_fill(cairo); + Cairo.cairo_destroy(cairo); this.width = width; this.height = height; } else { diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/internal/ImageList.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/internal/ImageList.java index 4274870c69..9de4dbeff5 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/internal/ImageList.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/internal/ImageList.java @@ -26,10 +26,30 @@ public ImageList() { pixbufs = new int /*long*/ [4]; } +public static int /*long*/ convertSurface(Image image) { + int /*long*/ newSurface = image.surface; + int type = Cairo.cairo_surface_get_type(newSurface); + if (type != Cairo.CAIRO_SURFACE_TYPE_IMAGE) { + Rectangle bounds = image.getBounds(); + int format = Cairo.cairo_surface_get_content(newSurface) == Cairo.CAIRO_CONTENT_COLOR ? Cairo.CAIRO_FORMAT_RGB24 : Cairo.CAIRO_FORMAT_ARGB32; + newSurface = Cairo.cairo_image_surface_create(format, bounds.width, bounds.height); + if (newSurface == 0) SWT.error(SWT.ERROR_NO_HANDLES); + int /*long*/ cairo = Cairo.cairo_create(newSurface); + if (cairo == 0) SWT.error(SWT.ERROR_NO_HANDLES); + Cairo.cairo_set_operator(cairo, Cairo.CAIRO_OPERATOR_SRC); + Cairo.cairo_set_source_surface (cairo, image.surface, 0, 0); + Cairo.cairo_paint (cairo); + Cairo.cairo_destroy(cairo); + } else { + Cairo.cairo_surface_reference(newSurface); + } + return newSurface; +} + public static int /*long*/ createPixbuf(Image image) { int /*long*/ pixbuf; if (OS.USE_CAIRO) { - int /*long*/ surface = image.surface; + int /*long*/ surface = convertSurface(image); int format = Cairo.cairo_image_surface_get_format(surface); int width = Cairo.cairo_image_surface_get_width(surface); int height = Cairo.cairo_image_surface_get_height(surface); @@ -79,6 +99,7 @@ public static int /*long*/ createPixbuf(Image image) { OS.memmove (pixels + (y * stride), line, stride); } } + Cairo.cairo_surface_destroy(surface); } else { int [] w = new int [1], h = new int [1]; OS.gdk_drawable_get_size (image.pixmap, w, h); |