mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-04-25 08:30:39 +02:00
gl: Add support for OpenGL ES 3.0
This improves the OpenGL ES support to extend it to version 3.0. A number of new features are available in glesv3 including creation of multi-sampled renderbuffers. These renderbuffers can be blitted to single sample textures (but not the other way around). Other features such as PBO for image uploading, are left as followon work. For this preliminary implementation, glesv3 backends always create renderbuffers, which can be set as single sample or multisample. The renderbuffer's content is blitted to the texture only when used as a source or a mask. Images uploaded to a texture stay there until the surface is used as a rendering target, at which point its painted to the renderbuffer. This patch is heavily based off of Henry Song's initial GLESv3 patch 6f7f3795 from his cairogles fork of Cairo, and incorporates subsequent fixes and pertinent refactorings from his trunk and review feedback from Uli. This implements the *functional* support for glesv3, excluding the various optimization work to utilize its features. Rendering and performance should not be expected to improve notably from pure glesv2. As the GL backend for Cairo remains "experimental", these changes should likewise be considered as such. Signed-off-by: Bryce Harrington <bryce@osg.samsung.com>
This commit is contained in:
parent
d1f941d7ee
commit
8ff3019f51
20 changed files with 370 additions and 65 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
23
configure.ac
23
configure.ac
|
|
@ -385,6 +385,29 @@ CAIRO_ENABLE_SURFACE_BACKEND(glesv2, OpenGLESv2, no, [
|
|||
need_egl_functions=yes
|
||||
])
|
||||
|
||||
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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
#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;
|
||||
|
||||
#elif CAIRO_HAS_GL_SURFACE
|
||||
ctx->current_target = surface;
|
||||
_cairo_gl_context_bind_framebuffer (ctx, surface, FALSE);
|
||||
|
||||
#else
|
||||
ctx->current_target = surface;
|
||||
|
||||
#if CAIRO_HAS_GL_SURFACE
|
||||
_cairo_gl_context_bind_framebuffer (ctx, surface, FALSE);
|
||||
#endif
|
||||
|
||||
status = _cairo_gl_context_release (ctx, status);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue