diff options
-rw-r--r-- | boilerplate/Makefile.win32.features | 12 | ||||
-rw-r--r-- | boilerplate/cairo-boilerplate-egl.c | 30 | ||||
-rw-r--r-- | build/Makefile.win32.features | 1 | ||||
-rw-r--r-- | build/Makefile.win32.features-h | 3 | ||||
-rw-r--r-- | build/configure.ac.features | 1 | ||||
-rw-r--r-- | configure.ac | 23 | ||||
-rw-r--r-- | src/Makefile.sources | 4 | ||||
-rw-r--r-- | src/Makefile.win32.features | 16 | ||||
-rw-r--r-- | src/cairo-gl-composite.c | 103 | ||||
-rw-r--r-- | src/cairo-gl-device.c | 91 | ||||
-rw-r--r-- | src/cairo-gl-dispatch.c | 12 | ||||
-rw-r--r-- | src/cairo-gl-gradient-private.h | 9 | ||||
-rw-r--r-- | src/cairo-gl-gradient.c | 3 | ||||
-rw-r--r-- | src/cairo-gl-info.c | 4 | ||||
-rw-r--r-- | src/cairo-gl-msaa-compositor.c | 10 | ||||
-rw-r--r-- | src/cairo-gl-operand.c | 3 | ||||
-rw-r--r-- | src/cairo-gl-private.h | 20 | ||||
-rw-r--r-- | src/cairo-gl-shaders.c | 15 | ||||
-rw-r--r-- | src/cairo-gl-surface.c | 73 | ||||
-rw-r--r-- | src/cairo-gl.h | 2 |
20 files changed, 370 insertions, 65 deletions
diff --git a/boilerplate/Makefile.win32.features b/boilerplate/Makefile.win32.features index e60a95ba6..abb198dee 100644 --- a/boilerplate/Makefile.win32.features +++ b/boilerplate/Makefile.win32.features @@ -247,6 +247,18 @@ enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_glesv2_cxx_sources) enabled_cairo_boilerplate_sources += $(cairo_boilerplate_glesv2_sources) endif +unsupported_cairo_boilerplate_headers += $(cairo_boilerplate_glesv3_headers) +all_cairo_boilerplate_headers += $(cairo_boilerplate_glesv3_headers) +all_cairo_boilerplate_private += $(cairo_boilerplate_glesv3_private) +all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_glesv3_cxx_sources) +all_cairo_boilerplate_sources += $(cairo_boilerplate_glesv3_sources) +ifeq ($(CAIRO_HAS_GLESV3_SURFACE),1) +enabled_cairo_boilerplate_headers += $(cairo_boilerplate_glesv3_headers) +enabled_cairo_boilerplate_private += $(cairo_boilerplate_glesv3_private) +enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_glesv3_cxx_sources) +enabled_cairo_boilerplate_sources += $(cairo_boilerplate_glesv3_sources) +endif + unsupported_cairo_boilerplate_headers += $(cairo_boilerplate_cogl_headers) all_cairo_boilerplate_headers += $(cairo_boilerplate_cogl_headers) all_cairo_boilerplate_private += $(cairo_boilerplate_cogl_private) diff --git a/boilerplate/cairo-boilerplate-egl.c b/boilerplate/cairo-boilerplate-egl.c index 99bee64cf..c44441cc5 100644 --- a/boilerplate/cairo-boilerplate-egl.c +++ b/boilerplate/cairo-boilerplate-egl.c @@ -33,10 +33,13 @@ #include "cairo-boilerplate-private.h" #include <cairo-gl.h> -#if CAIRO_HAS_GL_SURFACE -#include <GL/gl.h> +#if CAIRO_HAS_GLESV3_SURFACE +#include <GLES3/gl3.h> +#include <EGL/eglext.h> #elif CAIRO_HAS_GLESV2_SURFACE #include <GLES2/gl2.h> +#elif CAIRO_HAS_GL_SURFACE +#include <GL/gl.h> #endif static const cairo_user_data_key_t gl_closure_key; @@ -85,15 +88,19 @@ _cairo_boilerplate_egl_create_surface (const char *name, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, -#if CAIRO_HAS_GL_SURFACE - EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, +#if CAIRO_HAS_GLESV3_SURFACE + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR, #elif CAIRO_HAS_GLESV2_SURFACE EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, +#elif CAIRO_HAS_GL_SURFACE + EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, #endif EGL_NONE }; const EGLint ctx_attribs[] = { -#if CAIRO_HAS_GLESV2_SURFACE +#if CAIRO_HAS_GLESV3_SURFACE + EGL_CONTEXT_CLIENT_VERSION, 3, +#elif CAIRO_HAS_GLESV2_SURFACE EGL_CONTEXT_CLIENT_VERSION, 2, #endif EGL_NONE @@ -110,15 +117,22 @@ _cairo_boilerplate_egl_create_surface (const char *name, } eglChooseConfig (gltc->dpy, config_attribs, &config, 1, &numConfigs); +#if CAIRO_HAS_GLESV3_SURFACE && CAIRO_HAS_GLESV2_SURFACE + if (numConfigs == 0) { + /* retry with ES2_BIT */ + config_attribs[11] = ES2_BIT; /* FIXME: Ick */ + eglChooseConfig (gltc->dpy, config_attribs, &config, 1, &numConfigs); + } +#endif if (numConfigs == 0) { free (gltc); return NULL; } -#if CAIRO_HAS_GL_SURFACE - eglBindAPI (EGL_OPENGL_API); -#elif CAIRO_HAS_GLESV2_SURFACE +#if CAIRO_HAS_GLESV3_SURFACE || CAIRO_HAS_GLESV2_SURFACE eglBindAPI (EGL_OPENGL_ES_API); +#elif CAIRO_HAS_GL_SURFACE + eglBindAPI (EGL_OPENGL_API); #endif gltc->ctx = eglCreateContext (gltc->dpy, config, EGL_NO_CONTEXT, diff --git a/build/Makefile.win32.features b/build/Makefile.win32.features index 8cb155dc0..7f62d975e 100644 --- a/build/Makefile.win32.features +++ b/build/Makefile.win32.features @@ -19,6 +19,7 @@ CAIRO_HAS_GALLIUM_SURFACE=0 CAIRO_HAS_PNG_FUNCTIONS=1 CAIRO_HAS_GL_SURFACE=0 CAIRO_HAS_GLESV2_SURFACE=0 +CAIRO_HAS_GLESV3_SURFACE=0 CAIRO_HAS_COGL_SURFACE=0 CAIRO_HAS_DIRECTFB_SURFACE=0 CAIRO_HAS_VG_SURFACE=0 diff --git a/build/Makefile.win32.features-h b/build/Makefile.win32.features-h index 13904cfa9..2825f0c3c 100644 --- a/build/Makefile.win32.features-h +++ b/build/Makefile.win32.features-h @@ -62,6 +62,9 @@ endif ifeq ($(CAIRO_HAS_GLESV2_SURFACE),1) @echo "#define CAIRO_HAS_GLESV2_SURFACE 1" >> $(top_srcdir)/src/cairo-features.h endif +ifeq ($(CAIRO_HAS_GLESV3_SURFACE),1) + @echo "#define CAIRO_HAS_GLESV3_SURFACE 1" >> $(top_srcdir)/src/cairo-features.h +endif ifeq ($(CAIRO_HAS_COGL_SURFACE),1) @echo "#define CAIRO_HAS_COGL_SURFACE 1" >> $(top_srcdir)/src/cairo-features.h endif diff --git a/build/configure.ac.features b/build/configure.ac.features index 77f203588..aa48652f2 100644 --- a/build/configure.ac.features +++ b/build/configure.ac.features @@ -384,6 +384,7 @@ AC_DEFUN([CAIRO_REPORT], echo " SVG: $use_svg" echo " OpenGL: $use_gl" echo " OpenGL ES 2.0: $use_glesv2" + echo " OpenGL ES 3.0: $use_glesv3" echo " BeOS: $use_beos" echo " DirectFB: $use_directfb" echo " OpenVG: $use_vg" diff --git a/configure.ac b/configure.ac index 93953a7f2..264623d8a 100644 --- a/configure.ac +++ b/configure.ac @@ -386,6 +386,29 @@ CAIRO_ENABLE_SURFACE_BACKEND(glesv2, OpenGLESv2, no, [ ]) dnl =========================================================================== +CAIRO_ENABLE_SURFACE_BACKEND(glesv3, OpenGLESv3, no, [ + glesv3_REQUIRES="glesv3" + PKG_CHECK_MODULES(glesv3, $glesv3_REQUIRES,, [ + dnl Fallback to searching for headers + AC_CHECK_HEADER(GLES3/gl3.h,, [use_glesv3="no (glesv3.pc nor OpenGL ES 3.0 headers not found)"]) + if test "x$use_glesv3" = "xyes"; then + glesv3_NONPKGCONFIG_CFLAGS= + dnl glesv3 is provided by the libGLESv2 library (there is no separate libGLESv3) + glesv3_NONPKGCONFIG_LIBS="-lGLESv2" + fi]) + + if test "x$have_dl" = "xyes" -a "x$have_dlsym" = "xyes"; then + glesv3_LIBS="$glesv3_LIBS -ldl" + fi + + if test "x$use_glesv3" = "xyes" -a "x$use_gl" = "xyes"; then + AC_MSG_ERROR([use either --enable-gl=yes or --enable-glesv3=yes. Not both at the same time.]) + fi + + need_egl_functions=yes +]) + +dnl =========================================================================== CAIRO_ENABLE_SURFACE_BACKEND(cogl, Cogl, no, [ cogl_REQUIRES="cogl-2.0-experimental" PKG_CHECK_MODULES(cogl, $cogl_REQUIRES,, [use_cogl="no"]) diff --git a/src/Makefile.sources b/src/Makefile.sources index b1e3eb13e..89417ac86 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -407,6 +407,10 @@ cairo_glesv2_headers = $(cairo_gl_headers) cairo_glesv2_private = $(cairo_gl_private) cairo_glesv2_sources = $(cairo_gl_sources) +cairo_glesv3_headers = $(cairo_gl_headers) +cairo_glesv3_private = $(cairo_gl_private) +cairo_glesv3_sources = $(cairo_gl_sources) + cairo_egl_sources += cairo-egl-context.c cairo_glx_sources += cairo-glx-context.c cairo_wgl_sources += cairo-wgl-context.c diff --git a/src/Makefile.win32.features b/src/Makefile.win32.features index 2274f4ad6..e8be9f748 100644 --- a/src/Makefile.win32.features +++ b/src/Makefile.win32.features @@ -325,6 +325,22 @@ ifeq ($(CAIRO_HAS_GLESV2_SURFACE),1) enabled_cairo_pkgconf += cairo-glesv2.pc endif +unsupported_cairo_headers += $(cairo_glesv3_headers) +all_cairo_headers += $(cairo_glesv3_headers) +all_cairo_private += $(cairo_glesv3_private) +all_cairo_cxx_sources += $(cairo_glesv3_cxx_sources) +all_cairo_sources += $(cairo_glesv3_sources) +ifeq ($(CAIRO_HAS_GLESV3_SURFACE),1) +enabled_cairo_headers += $(cairo_glesv3_headers) +enabled_cairo_private += $(cairo_glesv3_private) +enabled_cairo_cxx_sources += $(cairo_glesv3_cxx_sources) +enabled_cairo_sources += $(cairo_glesv3_sources) +endif +all_cairo_pkgconf += cairo-glesv3.pc +ifeq ($(CAIRO_HAS_GLESV3_SURFACE),1) +enabled_cairo_pkgconf += cairo-glesv3.pc +endif + unsupported_cairo_headers += $(cairo_cogl_headers) all_cairo_headers += $(cairo_cogl_headers) all_cairo_private += $(cairo_cogl_private) diff --git a/src/cairo-gl-composite.c b/src/cairo-gl-composite.c index a95712e1c..ecf03a559 100644 --- a/src/cairo-gl-composite.c +++ b/src/cairo-gl-composite.c @@ -52,6 +52,93 @@ #include "cairo-error-private.h" #include "cairo-image-surface-private.h" +/* FIXME: Copy of same routine in cairo-gl-msaa-compositor.c */ +static cairo_int_status_t +_draw_int_rect (cairo_gl_context_t *ctx, + cairo_gl_composite_t *setup, + cairo_rectangle_int_t *rect) +{ + cairo_box_t box; + cairo_point_t quad[4]; + + _cairo_box_from_rectangle (&box, rect); + quad[0].x = box.p1.x; + quad[0].y = box.p1.y; + quad[1].x = box.p1.x; + quad[1].y = box.p2.y; + quad[2].x = box.p2.x; + quad[2].y = box.p2.y; + quad[3].x = box.p2.x; + quad[3].y = box.p1.y; + + return _cairo_gl_composite_emit_quad_as_tristrip (ctx, setup, quad); +} + +static cairo_int_status_t +_blit_texture_to_renderbuffer (cairo_gl_surface_t *surface) +{ + cairo_gl_context_t *ctx = NULL; + cairo_gl_composite_t setup; + cairo_surface_pattern_t pattern; + cairo_rectangle_int_t extents; + cairo_int_status_t status; + + /* FIXME: This only permits blit when glesv3 is enabled. But note that + glesv2 with the ANGLE extension should also be able to support this feature, + so once the ANGLE support code is in place this check can be relaxed. */ + if (((cairo_gl_context_t *)surface->base.device)->gl_flavor != CAIRO_GL_FLAVOR_ES3) + return CAIRO_INT_STATUS_SUCCESS; + + if (! surface->content_in_texture) + return CAIRO_INT_STATUS_SUCCESS; + + memset (&setup, 0, sizeof (cairo_gl_composite_t)); + + status = _cairo_gl_composite_set_operator (&setup, + CAIRO_OPERATOR_SOURCE, + FALSE); + + if (status) + return status; + + setup.dst = surface; + setup.clip_region = surface->clip_region; + + _cairo_pattern_init_for_surface (&pattern, &surface->base); + status = _cairo_gl_composite_set_source (&setup, &pattern.base, + NULL, NULL, FALSE); + _cairo_pattern_fini (&pattern.base); + + if (unlikely (status)) + goto FAIL; + + _cairo_gl_composite_set_multisample (&setup); + + status = _cairo_gl_composite_begin (&setup, &ctx); + + if (unlikely (status)) + goto FAIL; + + extents.x = extents.y = 0; + extents.width = surface->width; + extents.height = surface->height; + + status = _draw_int_rect (ctx, &setup, &extents); + + if (status == CAIRO_INT_STATUS_SUCCESS) + surface->content_in_texture = FALSE; + +FAIL: + _cairo_gl_composite_fini (&setup); + + if (ctx) { + _cairo_gl_composite_flush (ctx); + status = _cairo_gl_context_release (ctx, status); + } + + return status; +} + cairo_int_status_t _cairo_gl_composite_set_source (cairo_gl_composite_t *setup, const cairo_pattern_t *pattern, @@ -68,8 +155,13 @@ void _cairo_gl_composite_set_source_operand (cairo_gl_composite_t *setup, const cairo_gl_operand_t *source) { + cairo_int_status_t status; + _cairo_gl_operand_destroy (&setup->src); _cairo_gl_operand_copy (&setup->src, source); + + if (source->type == CAIRO_GL_OPERAND_TEXTURE) + status = _cairo_gl_surface_resolve_multisampling (source->texture.surface); } void @@ -99,9 +191,13 @@ void _cairo_gl_composite_set_mask_operand (cairo_gl_composite_t *setup, const cairo_gl_operand_t *mask) { + cairo_int_status_t status; _cairo_gl_operand_destroy (&setup->mask); - if (mask) + if (mask) { _cairo_gl_operand_copy (&setup->mask, mask); + if (mask->type == CAIRO_GL_OPERAND_TEXTURE) + status = _cairo_gl_surface_resolve_multisampling (mask->texture.surface); + } } void @@ -174,7 +270,8 @@ _cairo_gl_texture_set_extend (cairo_gl_context_t *ctx, switch (extend) { case CAIRO_EXTEND_NONE: - if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2) + if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3 || + ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2) wrap_mode = GL_CLAMP_TO_EDGE; else wrap_mode = GL_CLAMP_TO_BORDER; @@ -1178,6 +1275,8 @@ _cairo_gl_composite_init (cairo_gl_composite_t *setup, { cairo_status_t status; + status = _blit_texture_to_renderbuffer (dst); + memset (setup, 0, sizeof (cairo_gl_composite_t)); status = _cairo_gl_composite_set_operator (setup, op, diff --git a/src/cairo-gl-device.c b/src/cairo-gl-device.c index 2f56a5fd8..38582fd24 100644 --- a/src/cairo-gl-device.c +++ b/src/cairo-gl-device.c @@ -171,7 +171,8 @@ test_can_read_bgra (cairo_gl_flavor_t gl_flavor) if (gl_flavor == CAIRO_GL_FLAVOR_DESKTOP) return TRUE; - assert (gl_flavor == CAIRO_GL_FLAVOR_ES2); + assert (gl_flavor == CAIRO_GL_FLAVOR_ES3 || + gl_flavor == CAIRO_GL_FLAVOR_ES2); /* For OpenGL ES we have to look for the specific extension and BGRA only * matches cairo's integer packed bytes on little-endian machines. */ @@ -190,7 +191,8 @@ _cairo_gl_context_init (cairo_gl_context_t *ctx) int n; cairo_bool_t is_desktop = gl_flavor == CAIRO_GL_FLAVOR_DESKTOP; - cairo_bool_t is_gles = gl_flavor == CAIRO_GL_FLAVOR_ES2; + cairo_bool_t is_gles = (gl_flavor == CAIRO_GL_FLAVOR_ES3 || + gl_flavor == CAIRO_GL_FLAVOR_ES2); _cairo_device_init (&ctx->base, &_cairo_gl_device_backend); @@ -263,25 +265,31 @@ _cairo_gl_context_init (cairo_gl_context_t *ctx) } #endif -#if CAIRO_HAS_GLESV2_SURFACE && defined(GL_MAX_SAMPLES_EXT) +#if CAIRO_HAS_GLESV3_SURFACE + if (is_gles && ctx->has_packed_depth_stencil) { + glGetIntegerv(GL_MAX_SAMPLES, &ctx->num_samples); + } + +#elif CAIRO_HAS_GLESV2_SURFACE && defined(GL_MAX_SAMPLES_EXT) if (is_gles && ctx->has_packed_depth_stencil && _cairo_gl_has_extension ("GL_EXT_multisampled_render_to_texture")) { glGetIntegerv(GL_MAX_SAMPLES_EXT, &ctx->num_samples); } -#endif -#if CAIRO_HAS_GLESV2_SURFACE && defined(GL_MAX_SAMPLES_IMG) if (is_gles && ctx->has_packed_depth_stencil && _cairo_gl_has_extension ("GL_IMG_multisampled_render_to_texture")) { glGetIntegerv(GL_MAX_SAMPLES_IMG, &ctx->num_samples); } #endif - ctx->supports_msaa = ctx->num_samples > 1; + /* we always use renderbuffer for rendering in glesv3 */ + if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3) + ctx->supports_msaa = TRUE; + else + ctx->supports_msaa = ctx->num_samples > 1; if (ctx->num_samples > MAX_MSAA_SAMPLES) ctx->num_samples = MAX_MSAA_SAMPLES; - ctx->current_operator = -1; ctx->gl_flavor = gl_flavor; @@ -349,13 +357,15 @@ _get_depth_stencil_format (cairo_gl_context_t *ctx) return GL_DEPTH_STENCIL; #endif -#if CAIRO_HAS_GLESV2_SURFACE +#if CAIRO_HAS_GLESV2_SURFACE && !CAIRO_HAS_GLESV3_SURFACE if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP) return GL_DEPTH24_STENCIL8_OES; #endif #if CAIRO_HAS_GL_SURFACE return GL_DEPTH_STENCIL; +#elif CAIRO_HAS_GLESV3_SURFACE + return GL_DEPTH24_STENCIL8; #elif CAIRO_HAS_GLESV2_SURFACE return GL_DEPTH24_STENCIL8_OES; #endif @@ -436,13 +446,14 @@ _cairo_gl_ensure_framebuffer (cairo_gl_context_t *ctx, str, status); } } -#if CAIRO_HAS_GL_SURFACE +#if CAIRO_HAS_GL_SURFACE || CAIRO_HAS_GLESV3_SURFACE static void _cairo_gl_ensure_multisampling (cairo_gl_context_t *ctx, cairo_gl_surface_t *surface) { assert (surface->supports_msaa); - assert (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP); + assert (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP || + ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3); if (surface->msaa_fb) return; @@ -460,7 +471,11 @@ _cairo_gl_ensure_multisampling (cairo_gl_context_t *ctx, this information. */ ctx->dispatch.RenderbufferStorageMultisample (GL_RENDERBUFFER, ctx->num_samples, +#if CAIRO_HAS_GLESV3_SURFACE + GL_RGBA8, +#else GL_RGBA, +#endif surface->width, surface->height); ctx->dispatch.FramebufferRenderbuffer (GL_FRAMEBUFFER, @@ -472,6 +487,11 @@ _cairo_gl_ensure_multisampling (cairo_gl_context_t *ctx, glDisable (GL_SCISSOR_TEST); glClearColor (0, 0, 0, 0); glClear (GL_COLOR_BUFFER_BIT); + + /* for glesv3 with multisample renderbuffer, we always render to + this renderbuffer */ + if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3) + surface->msaa_active = TRUE; } #endif @@ -484,8 +504,9 @@ _cairo_gl_ensure_msaa_depth_stencil_buffer (cairo_gl_context_t *ctx, return TRUE; _cairo_gl_ensure_framebuffer (ctx, surface); -#if CAIRO_HAS_GL_SURFACE - if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP) +#if CAIRO_HAS_GL_SURFACE || CAIRO_HAS_GLESV3_SURFACE + if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP || + ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3) _cairo_gl_ensure_multisampling (ctx, surface); #endif @@ -499,8 +520,9 @@ _cairo_gl_ensure_msaa_depth_stencil_buffer (cairo_gl_context_t *ctx, surface->width, surface->height); -#if CAIRO_HAS_GL_SURFACE - if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP) { +#if CAIRO_HAS_GL_SURFACE || CAIRO_HAS_GLESV3_SURFACE + if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP || + ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3) { dispatch->FramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, @@ -615,7 +637,7 @@ _gl_identity_ortho (GLfloat *m, #undef M } -#if CAIRO_HAS_GL_SURFACE +#if CAIRO_HAS_GL_SURFACE || CAIRO_HAS_GLESV3_SURFACE static void bind_multisample_framebuffer (cairo_gl_context_t *ctx, cairo_gl_surface_t *surface) @@ -624,14 +646,19 @@ bind_multisample_framebuffer (cairo_gl_context_t *ctx, cairo_bool_t scissor_test_enabled; assert (surface->supports_msaa); - assert (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP); + assert (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP || + ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3); _cairo_gl_ensure_framebuffer (ctx, surface); _cairo_gl_ensure_multisampling (ctx, surface); if (surface->msaa_active) { +#if CAIRO_HAS_GL_SURFACE glEnable (GL_MULTISAMPLE); +#endif ctx->dispatch.BindFramebuffer (GL_FRAMEBUFFER, surface->msaa_fb); + if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3) + surface->content_in_texture = FALSE; return; } @@ -642,7 +669,9 @@ bind_multisample_framebuffer (cairo_gl_context_t *ctx, glDisable (GL_STENCIL_TEST); glDisable (GL_SCISSOR_TEST); +#if CAIRO_HAS_GL_SURFACE glEnable (GL_MULTISAMPLE); +#endif /* The last time we drew to the surface, we were not using multisampling, so we need to blit from the non-multisampling framebuffer into the @@ -651,17 +680,24 @@ bind_multisample_framebuffer (cairo_gl_context_t *ctx, ctx->dispatch.BindFramebuffer (GL_READ_FRAMEBUFFER, surface->fb); ctx->dispatch.BlitFramebuffer (0, 0, surface->width, surface->height, 0, 0, surface->width, surface->height, - GL_COLOR_BUFFER_BIT, GL_NEAREST); + GL_COLOR_BUFFER_BIT +#if CAIRO_HAS_GL_SURFACE + | GL_STENCIL_BUFFER_BIT +#endif + , + GL_NEAREST); ctx->dispatch.BindFramebuffer (GL_FRAMEBUFFER, surface->msaa_fb); if (stencil_test_enabled) glEnable (GL_STENCIL_TEST); if (scissor_test_enabled) glEnable (GL_SCISSOR_TEST); + if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3) + surface->content_in_texture = FALSE; } #endif -#if CAIRO_HAS_GL_SURFACE +#if CAIRO_HAS_GL_SURFACE || CAIRO_HAS_GLESV3_SURFACE static void bind_singlesample_framebuffer (cairo_gl_context_t *ctx, cairo_gl_surface_t *surface) @@ -669,11 +705,15 @@ bind_singlesample_framebuffer (cairo_gl_context_t *ctx, cairo_bool_t stencil_test_enabled; cairo_bool_t scissor_test_enabled; - assert (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP); + assert (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP || + ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3); _cairo_gl_ensure_framebuffer (ctx, surface); if (! surface->msaa_active) { +#if CAIRO_HAS_GL_SURFACE glDisable (GL_MULTISAMPLE); +#endif + ctx->dispatch.BindFramebuffer (GL_FRAMEBUFFER, surface->fb); return; } @@ -685,7 +725,9 @@ bind_singlesample_framebuffer (cairo_gl_context_t *ctx, glDisable (GL_STENCIL_TEST); glDisable (GL_SCISSOR_TEST); +#if CAIRO_HAS_GL_SURFACE glDisable (GL_MULTISAMPLE); +#endif /* The last time we drew to the surface, we were using multisampling, so we need to blit from the multisampling framebuffer into the @@ -718,7 +760,7 @@ _cairo_gl_context_bind_framebuffer (cairo_gl_context_t *ctx, return; } -#if CAIRO_HAS_GL_SURFACE +#if CAIRO_HAS_GL_SURFACE || CAIRO_HAS_GLESV3_SURFACE if (multisampling) bind_multisample_framebuffer (ctx, surface); else @@ -737,7 +779,8 @@ _cairo_gl_context_bind_framebuffer (cairo_gl_context_t *ctx, #endif } - surface->msaa_active = multisampling; + if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP) + surface->msaa_active = multisampling; } void @@ -751,9 +794,13 @@ _cairo_gl_context_set_destination (cairo_gl_context_t *ctx, * we create an OpenGL ES surface, so we can never switch modes. */ if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2) multisampling = surface->msaa_active; + /* For GLESV3, we always use renderbuffer for drawing */ + else if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3) + multisampling = TRUE; changing_surface = ctx->current_target != surface || surface->needs_update; - changing_sampling = surface->msaa_active != multisampling; + changing_sampling = (surface->msaa_active != multisampling || + surface->content_in_texture); if (! changing_surface && ! changing_sampling) return; diff --git a/src/cairo-gl-dispatch.c b/src/cairo-gl-dispatch.c index 3e3721922..a49199dbb 100644 --- a/src/cairo-gl-dispatch.c +++ b/src/cairo-gl-dispatch.c @@ -124,6 +124,10 @@ _cairo_gl_dispatch_init_buffers (cairo_gl_dispatch_t *dispatch, else return CAIRO_STATUS_DEVICE_ERROR; } + else if (gl_flavor == CAIRO_GL_FLAVOR_ES3) + { + dispatch_name = CAIRO_GL_DISPATCH_NAME_CORE; + } else if (gl_flavor == CAIRO_GL_FLAVOR_ES2 && gl_version >= CAIRO_GL_VERSION_ENCODE (2, 0)) { @@ -156,6 +160,10 @@ _cairo_gl_dispatch_init_shaders (cairo_gl_dispatch_t *dispatch, else return CAIRO_STATUS_DEVICE_ERROR; } + else if (gl_flavor == CAIRO_GL_FLAVOR_ES3) + { + dispatch_name = CAIRO_GL_DISPATCH_NAME_CORE; + } else if (gl_flavor == CAIRO_GL_FLAVOR_ES2 && gl_version >= CAIRO_GL_VERSION_ENCODE (2, 0)) { @@ -189,6 +197,10 @@ _cairo_gl_dispatch_init_fbo (cairo_gl_dispatch_t *dispatch, else return CAIRO_STATUS_DEVICE_ERROR; } + else if (gl_flavor == CAIRO_GL_FLAVOR_ES3) + { + dispatch_name = CAIRO_GL_DISPATCH_NAME_CORE; + } else if (gl_flavor == CAIRO_GL_FLAVOR_ES2 && gl_version >= CAIRO_GL_VERSION_ENCODE (2, 0)) { diff --git a/src/cairo-gl-gradient-private.h b/src/cairo-gl-gradient-private.h index 77f9bbdc5..0d9f41f54 100644 --- a/src/cairo-gl-gradient-private.h +++ b/src/cairo-gl-gradient-private.h @@ -51,12 +51,15 @@ #include "cairo-gl.h" -#if CAIRO_HAS_GL_SURFACE -#include <GL/gl.h> -#include <GL/glext.h> +#if CAIRO_HAS_GLESV3_SURFACE +#include <GLES3/gl3.h> +#include <GLES3/gl3ext.h> #elif CAIRO_HAS_GLESV2_SURFACE #include <GLES2/gl2.h> #include <GLES2/gl2ext.h> +#elif CAIRO_HAS_GL_SURFACE +#include <GL/gl.h> +#include <GL/glext.h> #endif #define CAIRO_GL_GRADIENT_CACHE_SIZE 4096 diff --git a/src/cairo-gl-gradient.c b/src/cairo-gl-gradient.c index db82c23d8..0ab01ac3e 100644 --- a/src/cairo-gl-gradient.c +++ b/src/cairo-gl-gradient.c @@ -282,7 +282,8 @@ _cairo_gl_gradient_create (cairo_gl_context_t *ctx, * In OpenGL ES 2.0 no format conversion is allowed i.e. 'internalFormat' * must match 'format' in glTexImage2D. */ - if (_cairo_gl_get_flavor () == CAIRO_GL_FLAVOR_ES2) + if (_cairo_gl_get_flavor () == CAIRO_GL_FLAVOR_ES3 || + _cairo_gl_get_flavor () == CAIRO_GL_FLAVOR_ES2) internal_format = GL_BGRA; else internal_format = GL_RGBA; diff --git a/src/cairo-gl-info.c b/src/cairo-gl-info.c index a4b42715d..032e2568e 100644 --- a/src/cairo-gl-info.c +++ b/src/cairo-gl-info.c @@ -65,7 +65,9 @@ _cairo_gl_get_flavor (void) if (version == NULL) flavor = CAIRO_GL_FLAVOR_NONE; - else if (strstr (version, "OpenGL ES") != NULL) + else if (strstr (version, "OpenGL ES 3") != NULL) + flavor = CAIRO_GL_FLAVOR_ES3; + else if (strstr (version, "OpenGL ES 2") != NULL) flavor = CAIRO_GL_FLAVOR_ES2; else flavor = CAIRO_GL_FLAVOR_DESKTOP; diff --git a/src/cairo-gl-msaa-compositor.c b/src/cairo-gl-msaa-compositor.c index 507459de3..f9cd7c296 100644 --- a/src/cairo-gl-msaa-compositor.c +++ b/src/cairo-gl-msaa-compositor.c @@ -273,6 +273,8 @@ static cairo_bool_t can_use_msaa_compositor (cairo_gl_surface_t *surface, cairo_antialias_t antialias) { + cairo_gl_flavor_t gl_flavor = ((cairo_gl_context_t *) surface->base.device)->gl_flavor; + query_surface_capabilities (surface); if (! surface->supports_stencil) return FALSE; @@ -280,8 +282,10 @@ can_use_msaa_compositor (cairo_gl_surface_t *surface, /* Multisampling OpenGL ES surfaces only maintain one multisampling framebuffer and thus must use the spans compositor to do non-antialiased rendering. */ - if (((cairo_gl_context_t *) surface->base.device)->gl_flavor == CAIRO_GL_FLAVOR_ES2 + if ((gl_flavor == CAIRO_GL_FLAVOR_ES3 || + gl_flavor == CAIRO_GL_FLAVOR_ES2) && surface->supports_msaa + && surface->num_samples > 1 && antialias == CAIRO_ANTIALIAS_NONE) return FALSE; @@ -378,6 +382,9 @@ _cairo_gl_msaa_compositor_mask_source_operator (const cairo_compositor_t *compos FALSE); if (unlikely (status)) goto finish; + + _cairo_gl_context_set_destination (ctx, dst, setup.multisample); + status = _cairo_gl_set_operands_and_operator (&setup, ctx); if (unlikely (status)) goto finish; @@ -634,6 +641,7 @@ query_surface_capabilities (cairo_gl_surface_t *surface) glGetIntegerv(GL_STENCIL_BITS, &stencil_bits); surface->supports_stencil = stencil_bits > 0; surface->supports_msaa = samples > 1; + surface->num_samples = samples; status = _cairo_gl_context_release (ctx, status); } diff --git a/src/cairo-gl-operand.c b/src/cairo-gl-operand.c index ca1fa4b6b..8626329e0 100644 --- a/src/cairo-gl-operand.c +++ b/src/cairo-gl-operand.c @@ -658,7 +658,8 @@ _cairo_gl_operand_bind_to_shader (cairo_gl_context_t *ctx, * with CAIRO_EXTEND_NONE). When bilinear filtering is enabled, * these shaders need the texture dimensions for their calculations. */ - if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2 && + if ((ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3 || + ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2) && _cairo_gl_operand_get_extend (operand) == CAIRO_EXTEND_NONE && _cairo_gl_operand_get_gl_filter (operand) == GL_LINEAR) { diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h index b2d8545ce..f02a58763 100644 --- a/src/cairo-gl-private.h +++ b/src/cairo-gl-private.h @@ -60,12 +60,15 @@ #include <assert.h> -#if CAIRO_HAS_GL_SURFACE -#include <GL/gl.h> -#include <GL/glext.h> +#if CAIRO_HAS_GLESV3_SURFACE +#include <GLES3/gl3.h> +#include <GLES3/gl3ext.h> #elif CAIRO_HAS_GLESV2_SURFACE #include <GLES2/gl2.h> #include <GLES2/gl2ext.h> +#elif CAIRO_HAS_GL_SURFACE +#include <GL/gl.h> +#include <GL/glext.h> #endif #include "cairo-gl-ext-def-private.h" @@ -99,11 +102,12 @@ typedef struct _cairo_gl_surface cairo_gl_surface_t; -/* GL flavor */ +/* GL flavor is the type of GL supported by the underlying platform. */ typedef enum cairo_gl_flavor { CAIRO_GL_FLAVOR_NONE = 0, CAIRO_GL_FLAVOR_DESKTOP = 1, - CAIRO_GL_FLAVOR_ES2 = 2 + CAIRO_GL_FLAVOR_ES2 = 2, + CAIRO_GL_FLAVOR_ES3 = 3 } cairo_gl_flavor_t; /* Indices for vertex attributes used by BindAttribLocation, etc. */ @@ -169,7 +173,7 @@ struct _cairo_gl_surface { GLuint fb; /* GL framebuffer object wrapping our data. */ GLuint depth_stencil; /* GL renderbuffer object for holding stencil buffer clip. */ -#if CAIRO_HAS_GL_SURFACE +#if CAIRO_HAS_GL_SURFACE || CAIRO_HAS_GLESV3_SURFACE GLuint msaa_rb; /* The ARB MSAA path uses a renderbuffer. */ GLuint msaa_fb; #endif @@ -178,8 +182,12 @@ struct _cairo_gl_surface { cairo_bool_t stencil_and_msaa_caps_initialized; cairo_bool_t supports_stencil; /* Stencil support for for non-texture surfaces. */ cairo_bool_t supports_msaa; + GLint num_samples; cairo_bool_t msaa_active; /* Whether the multisampling framebuffer is active or not. */ + cairo_bool_t content_in_texture; /* whether we just uploaded image + to texture, used for certain + gles2 extensions and glesv3 */ cairo_clip_t *clip_on_stencil_buffer; int owns_tex; diff --git a/src/cairo-gl-shaders.c b/src/cairo-gl-shaders.c index aceb5d255..7d4fefbbc 100644 --- a/src/cairo-gl-shaders.c +++ b/src/cairo-gl-shaders.c @@ -398,7 +398,8 @@ cairo_gl_shader_emit_color (cairo_output_stream_t *stream, "vec4 get_%s()\n" "{\n", rectstr, namestr, namestr, namestr, namestr); - if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2 && + if ((ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3 || + ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2) && _cairo_gl_shader_needs_border_fade (op)) { _cairo_output_stream_printf (stream, @@ -425,7 +426,8 @@ cairo_gl_shader_emit_color (cairo_output_stream_t *stream, "vec4 get_%s()\n" "{\n", namestr, namestr, rectstr, namestr, namestr); - if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2 && + if ((ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3 || + ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2) && _cairo_gl_shader_needs_border_fade (op)) { _cairo_output_stream_printf (stream, @@ -462,7 +464,8 @@ cairo_gl_shader_emit_color (cairo_output_stream_t *stream, " float is_valid = step (-%s_radius_0, t * %s_circle_d.z);\n", namestr, namestr, rectstr, namestr, namestr, namestr, namestr, namestr, namestr, namestr, namestr, namestr); - if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2 && + if ((ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3 || + ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2) && _cairo_gl_shader_needs_border_fade (op)) { _cairo_output_stream_printf (stream, @@ -507,7 +510,8 @@ cairo_gl_shader_emit_color (cairo_output_stream_t *stream, " float upper_t = mix (t.y, t.x, is_valid.x);\n", namestr, namestr, rectstr, namestr, namestr, namestr, namestr, namestr, namestr, namestr, namestr, namestr, namestr); - if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2 && + if ((ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3 || + ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2) && _cairo_gl_shader_needs_border_fade (op)) { _cairo_output_stream_printf (stream, @@ -674,7 +678,8 @@ cairo_gl_shader_get_fragment_source (cairo_gl_context_t *ctx, _cairo_gl_shader_emit_wrap (ctx, stream, src, CAIRO_GL_TEX_SOURCE); _cairo_gl_shader_emit_wrap (ctx, stream, mask, CAIRO_GL_TEX_MASK); - if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2) { + if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3 || + ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2) { if (_cairo_gl_shader_needs_border_fade (src)) _cairo_gl_shader_emit_border_fade (stream, src, CAIRO_GL_TEX_SOURCE); if (_cairo_gl_shader_needs_border_fade (mask)) diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c index 8ecc3a92e..6be6d9868 100644 --- a/src/cairo-gl-surface.c +++ b/src/cairo-gl-surface.c @@ -395,6 +395,7 @@ _cairo_gl_surface_init (cairo_device_t *device, surface->width = width; surface->height = height; surface->needs_update = FALSE; + surface->content_in_texture = FALSE; _cairo_gl_surface_embedded_operand_init (surface); } @@ -433,6 +434,7 @@ _cairo_gl_surface_create_scratch_for_texture (cairo_gl_context_t *ctx, _cairo_gl_surface_init (&ctx->base, surface, content, width, height); surface->supports_msaa = ctx->supports_msaa; + surface->num_samples = ctx->num_samples; surface->supports_stencil = TRUE; /* Create the texture used to store the surface's data. */ @@ -875,7 +877,8 @@ _cairo_gl_surface_draw_image (cairo_gl_surface_t *dst, if (unlikely (status)) return status; - if (_cairo_gl_get_flavor () == CAIRO_GL_FLAVOR_ES2) { + if (_cairo_gl_get_flavor () == CAIRO_GL_FLAVOR_ES3 || + _cairo_gl_get_flavor () == CAIRO_GL_FLAVOR_ES2) { pixman_format_code_t pixman_format; cairo_surface_pattern_t pattern; cairo_bool_t require_conversion = FALSE; @@ -885,13 +888,12 @@ _cairo_gl_surface_draw_image (cairo_gl_surface_t *dst, if (src->pixman_format != pixman_format) require_conversion = TRUE; } - else if (dst->base.content != CAIRO_CONTENT_ALPHA) + else if (dst->base.content != CAIRO_CONTENT_ALPHA) { + require_conversion = TRUE; + } + else if (src->pixman_format != PIXMAN_a8) { + pixman_format = PIXMAN_a8; require_conversion = TRUE; - else { - if (src->pixman_format == PIXMAN_a1) { - pixman_format = PIXMAN_a8; - require_conversion = TRUE; - } } if (require_conversion) { @@ -980,10 +982,19 @@ _cairo_gl_surface_draw_image (cairo_gl_surface_t *dst, else { glPixelStorei (GL_UNPACK_ALIGNMENT, 4); - if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP) + if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP || + ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3) glPixelStorei (GL_UNPACK_ROW_LENGTH, src->stride / cpp); } + /* we must resolve the renderbuffer to texture before we + upload image */ + status = _cairo_gl_surface_resolve_multisampling (dst); + if (unlikely (status)) { + free (data_start_gles2); + goto FAIL; + } + _cairo_gl_context_activate (ctx, CAIRO_GL_TEX_TEMP); glBindTexture (ctx->tex_target, dst->tex); glTexParameteri (ctx->tex_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); @@ -1003,6 +1014,8 @@ _cairo_gl_surface_draw_image (cairo_gl_surface_t *dst, dst_x, dst_y, width, height); } + if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3) + dst->content_in_texture = TRUE; } else { cairo_surface_t *tmp; @@ -1042,6 +1055,8 @@ _cairo_gl_surface_draw_image (cairo_gl_surface_t *dst, } cairo_surface_destroy (tmp); + if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3) + dst->content_in_texture = TRUE; } FAIL: @@ -1092,7 +1107,7 @@ _cairo_gl_surface_finish (void *abstract_surface) if (surface->msaa_depth_stencil) ctx->dispatch.DeleteRenderbuffers (1, &surface->msaa_depth_stencil); -#if CAIRO_HAS_GL_SURFACE +#if CAIRO_HAS_GL_SURFACE || CAIRO_HAS_GLESV3_SURFACE if (surface->msaa_fb) ctx->dispatch.DeleteFramebuffers (1, &surface->msaa_fb); if (surface->msaa_rb) @@ -1144,7 +1159,8 @@ _cairo_gl_surface_map_to_image (void *abstract_surface, return NULL; } - if (_cairo_gl_surface_flavor (surface) == CAIRO_GL_FLAVOR_ES2) { + if (_cairo_gl_surface_flavor (surface) == CAIRO_GL_FLAVOR_ES3 || + _cairo_gl_surface_flavor (surface) == CAIRO_GL_FLAVOR_ES2) { /* If only RGBA is supported, we must download data in a compatible * format. This means that pixman will convert the data on the CPU when * interacting with other image surfaces. For ALPHA, GLES2 does not @@ -1193,13 +1209,29 @@ _cairo_gl_surface_map_to_image (void *abstract_surface, * fall back instead. */ _cairo_gl_composite_flush (ctx); - _cairo_gl_context_set_destination (ctx, surface, FALSE); + + if (ctx->gl_flavor != CAIRO_GL_FLAVOR_ES3) { + _cairo_gl_context_set_destination (ctx, surface, FALSE); + } else { + if (surface->content_in_texture) { + _cairo_gl_ensure_framebuffer (ctx, surface); + ctx->dispatch.BindFramebuffer (GL_FRAMEBUFFER, surface->fb); + } else { + status = _cairo_gl_surface_resolve_multisampling (surface); + if (unlikely (status)) { + status = _cairo_gl_context_release (ctx, status); + cairo_surface_destroy (&image->base); + return _cairo_image_surface_create_in_error (status); + } + } + } flipped = ! _cairo_gl_surface_is_texture (surface); mesa_invert = flipped && ctx->has_mesa_pack_invert; glPixelStorei (GL_PACK_ALIGNMENT, 4); - if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP) + if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP || + ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3) glPixelStorei (GL_PACK_ROW_LENGTH, image->stride / cpp); if (mesa_invert) glPixelStorei (GL_PACK_INVERT_MESA, 1); @@ -1366,6 +1398,9 @@ _cairo_gl_surface_resolve_multisampling (cairo_gl_surface_t *surface) /* GLES surfaces do not need explicit resolution. */ if (((cairo_gl_context_t *) surface->base.device)->gl_flavor == CAIRO_GL_FLAVOR_ES2) return CAIRO_INT_STATUS_SUCCESS; + else if (((cairo_gl_context_t *) surface->base.device)->gl_flavor == CAIRO_GL_FLAVOR_ES3 && + surface->content_in_texture) + return CAIRO_INT_STATUS_SUCCESS; if (! _cairo_gl_surface_is_texture (surface)) return CAIRO_INT_STATUS_SUCCESS; @@ -1374,10 +1409,20 @@ _cairo_gl_surface_resolve_multisampling (cairo_gl_surface_t *surface) if (unlikely (status)) return status; - ctx->current_target = surface; +#if CAIRO_HAS_GLESV3_SURFACE + _cairo_gl_composite_flush (ctx); + ctx->current_target = NULL; + _cairo_gl_context_bind_framebuffer (ctx, surface, FALSE); + if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3) + surface->content_in_texture = TRUE; -#if CAIRO_HAS_GL_SURFACE +#elif CAIRO_HAS_GL_SURFACE + ctx->current_target = surface; _cairo_gl_context_bind_framebuffer (ctx, surface, FALSE); + +#else + ctx->current_target = surface; + #endif status = _cairo_gl_context_release (ctx, status); diff --git a/src/cairo-gl.h b/src/cairo-gl.h index 9fd7608f5..7cd869c76 100644 --- a/src/cairo-gl.h +++ b/src/cairo-gl.h @@ -62,7 +62,7 @@ #include "cairo.h" -#if CAIRO_HAS_GL_SURFACE || CAIRO_HAS_GLESV2_SURFACE +#if CAIRO_HAS_GL_SURFACE || CAIRO_HAS_GLESV2_SURFACE || CAIRO_HAS_GLESV3_SURFACE CAIRO_BEGIN_DECLS |