putenv("EVAS_GL_API_DEBUG=1"); \
evas_init(); \
ecore_evas_init(); \
- ee = ecore_evas_new(engine, 0, 0, 1, 1, options); \
+ if (!options || !strcmp(engine, "buffer")) ee = ecore_evas_new(engine, 0, 0, 1, 1, NULL); \
+ else ee = ecore_evas_gl_x11_options_new(NULL, NULL, 0, 0, 1, 1, options); \
if (!ee) { printf("Could not create ecore evas. Skipping Evas GL tests.\n"); \
goto init_failed; } \
ecore_evas_show(ee); \
do {} while (0)
static void
-_test_evasgl_init(const char *engine, const char *options)
+_test_evasgl_init(const char *engine)
{
- START_EVASGL_TEST(engine, options);
+ START_EVASGL_TEST(engine, NULL);
Evas_GL_Context *ctx;
Evas_GL_Surface *sfc;
Evas_GL_Config *cfg;
}
static void
-_test_evasgl_current_get(const char *engine, const char *options)
+_test_evasgl_current_get(const char *engine)
{
- if (!_detect_osmesa())
- return;
-
- START_EVASGL_TEST(engine, options);
+ START_EVASGL_TEST(engine, NULL);
Evas_GL_Context *ctx, *ctx2;
Evas_GL_Surface *sfc, *sfc2;
Evas_GL_Config *cfg;
fail_if(evgl2 != evgl);
fail_if(sfc2 != sfc);
fail_if(ctx2 != ctx);
+ fail_if(evas_gl_current_surface_get(evgl) != sfc);
+ fail_if(evas_gl_current_context_get(evgl) != ctx);
fail_if(!evas_gl_make_current(evgl, NULL, NULL));
evgl2 = evas_gl_current_evas_gl_get(&ctx2, &sfc2);
fail_if(evgl2 != evgl); /* this should not reset current Evas GL */
fail_if(sfc2 != NULL);
fail_if(ctx2 != NULL);
+ fail_if(evas_gl_current_surface_get(evgl));
+ fail_if(evas_gl_current_context_get(evgl));
evas_gl_context_destroy(evgl, ctx);
evas_gl_surface_destroy(evgl, sfc);
}
static void
-_test_evasgl_context_version(const char *engine, const char *options)
+_test_evasgl_context_version(const char *engine)
{
- if (!_detect_osmesa())
- return;
-
- START_EVASGL_TEST(engine, options);
+ START_EVASGL_TEST(engine, NULL);
Evas_GL_Context *ctx, *ctx2;
Evas_GL_Surface *sfc;
Evas_GL_Config *cfg;
}
static void
-_test_evasgl_surfaceless_context(const char *engine, const char *options)
+_test_evasgl_surfaceless_context(const char *engine)
{
- if (!_detect_osmesa())
- return;
-
- START_EVASGL_TEST(engine, options);
+ START_EVASGL_TEST(engine, NULL);
Evas_GL_Context *ctx;
Evas_GL_Surface *sfc;
Evas_GL_Config *cfg;
fail_if(!(evgl = evas_gl_new(evas)));
fail_if(!(ctx = evas_gl_context_create(evgl, NULL)));
- // FIXME: evas_gl_string_query will fail before the first make_current
+ // FIXME: evas_gl_string_query will fail before the first make_current (GL)
fail_if(!(cfg = evas_gl_config_new()));
fail_if(!(sfc = evas_gl_surface_create(evgl, cfg, 1, 1)));
fail_if(!evas_gl_make_current(evgl, sfc, ctx));
// FIXME
+ fail_if(!(gl = evas_gl_context_api_get(evgl, ctx)));
+
eexts = evas_gl_string_query(evgl, EVAS_GL_EXTENSIONS);
if (eexts && strstr(eexts, "EGL_KHR_surfaceless_context"))
{
fail_if(!evas_gl_make_current(evgl, NULL, ctx));
- fail_if(!(gl = evas_gl_context_api_get(evgl, ctx)));
fail_if(!gl->glGetString(GL_VERSION));
}
else printf("Surfaceless context not supported. Skipped.\n");
fail_if(!evas_gl_make_current(evgl, NULL, NULL));
evas_gl_context_destroy(evgl, ctx);
+ evas_gl_surface_destroy(evgl, sfc);
+ evas_gl_config_free(cfg);
+ evas_gl_free(evgl);
+ END_EVASGL_TEST();
+}
+
+static void
+_test_evasgl_glreadpixels(const char *engine)
+{
+ /* simple test verifying surface render works as expected */
+
+ START_EVASGL_TEST(engine, NULL);
+ Evas_GL_Context *ctx;
+ Evas_GL_Surface *sfc;
+ Evas_GL_Config *cfg;
+ Evas_GL_API *gl;
+ Evas_GL *evgl;
+ unsigned int pixel;
+
+ fail_if(!(evgl = evas_gl_new(evas)));
+ fail_if(!(cfg = evas_gl_config_new()));
+ fail_if(!(ctx = evas_gl_context_create(evgl, NULL)));
+ fail_if(!(sfc = evas_gl_surface_create(evgl, cfg, 1, 1)));
+ fail_if(!evas_gl_make_current(evgl, sfc, ctx));
+ fail_if(!(gl = evas_gl_context_api_get(evgl, ctx)));
+
+ gl->glClearColor(0, 1, 0, 1);
+ gl->glClear(GL_COLOR_BUFFER_BIT);
+ gl->glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel);
+ fail_if(gl->glGetError() != GL_NO_ERROR);
+ fail_if(pixel != 0xFF00FF00);
+
+ fail_if(!evas_gl_make_current(evgl, NULL, NULL));
+ evas_gl_context_destroy(evgl, ctx);
+ evas_gl_surface_destroy(evgl, sfc);
+ evas_gl_config_free(cfg);
+ evas_gl_free(evgl);
+ END_EVASGL_TEST();
+}
+
+static void
+_test_evasgl_fbo(const char *engine)
+{
+ /* simple test verifying FBO render works as expected */
+
+ START_EVASGL_TEST(engine, NULL);
+ Evas_GL_Context *ctx;
+ Evas_GL_Surface *sfc;
+ Evas_GL_Config *cfg;
+ Evas_GL_API *gl;
+ Evas_GL *evgl;
+ unsigned int pixel;
+ GLuint fbo, tex, vtx, frg, prg, u;
+ GLint status;
+
+ static const char *vertex =
+ "precision mediump float;\n"
+ "attribute vec4 vertex;\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = vertex;\n"
+ "}\n";
+ static const char *fragment =
+ "precision mediump float;\n"
+ "uniform vec4 color;\n"
+ "void main()\n"
+ "{\n"
+ " gl_FragColor = color;\n"
+ "}\n";
+ static const GLfloat color[] = { 1, 0, 0, 1 };
+ static const GLfloat vertices[] = {
+ 1.0, 1.0, 0.0,
+ -1.0, -1.0, 0.0,
+ 1.0, -1.0, 0.0,
+ 1.0, 1.0, 0.0,
+ -1.0, 1.0, 0.0,
+ -1.0, -1.0, 0.0
+ };
+
+ /* surface & context */
+ fail_if(!(evgl = evas_gl_new(evas)));
+ fail_if(!(cfg = evas_gl_config_new()));
+ cfg->color_format = EVAS_GL_RGBA_8888;
+ fail_if(!(ctx = evas_gl_context_create(evgl, NULL)));
+ fail_if(!(sfc = evas_gl_surface_create(evgl, cfg, 1, 1)));
+ fail_if(!evas_gl_make_current(evgl, sfc, ctx));
+ fail_if(!(gl = evas_gl_context_api_get(evgl, ctx)));
+
+ /* generate fbo */
+ gl->glGenFramebuffers(1, &fbo);
+ gl->glGenTextures(1, &tex);
+ gl->glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ gl->glBindTexture(GL_TEXTURE_2D, tex);
+ gl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ gl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ gl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ gl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ gl->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ gl->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
+ fail_if(gl->glGetError() != GL_NO_ERROR);
+
+ /* prepare program */
+ vtx = gl->glCreateShader(GL_VERTEX_SHADER);
+ gl->glShaderSource(vtx, 1, &vertex, NULL);
+ gl->glCompileShader(vtx);
+ gl->glGetShaderiv(vtx, GL_COMPILE_STATUS, &status);
+ fail_if((gl->glGetError() != GL_NO_ERROR) || !status);
+ frg = gl->glCreateShader(GL_FRAGMENT_SHADER);
+ gl->glShaderSource(frg, 1, &fragment, NULL);
+ gl->glCompileShader(frg);
+ gl->glGetShaderiv(frg, GL_COMPILE_STATUS, &status);
+ fail_if((gl->glGetError() != GL_NO_ERROR) || !status);
+ prg = gl->glCreateProgram();
+ gl->glAttachShader(prg, vtx);
+ gl->glAttachShader(prg, frg);
+ gl->glBindAttribLocation(prg, 0, "vertex");
+ gl->glLinkProgram(prg);
+ gl->glGetProgramiv(prg, GL_LINK_STATUS, &status);
+ fail_if((gl->glGetError() != GL_NO_ERROR) || !status);
+
+ /* clear */
+ gl->glClearColor(0, 0, 0, 0);
+ gl->glClear(GL_COLOR_BUFFER_BIT);
+ fail_if(gl->glGetError() != GL_NO_ERROR);
+
+ /* set parameters */
+ gl->glUseProgram(prg);
+ u = gl->glGetUniformLocation(prg, "color");
+ gl->glUniform4fv(u, 1, color);
+ gl->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vertices);
+ gl->glEnableVertexAttribArray(0);
+ fail_if(gl->glGetError() != GL_NO_ERROR);
+
+ /* draw */
+ gl->glDrawArrays(GL_TRIANGLES, 0, 6);
+ gl->glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel);
+ fail_if(gl->glGetError() != GL_NO_ERROR);
+ fail_if(pixel != 0xFF0000FF);
+
+ fail_if(!evas_gl_make_current(evgl, NULL, NULL));
+ evas_gl_context_destroy(evgl, ctx);
+ evas_gl_surface_destroy(evgl, sfc);
+ evas_gl_config_free(cfg);
+ evas_gl_free(evgl);
+ END_EVASGL_TEST();
+}
+
+static void
+_test_evasgl_pbuffer(const char *engine)
+{
+ /* check support for PBuffer */
+
+ // FIXME: No SW engine support!
+ if (!strcmp(engine, "buffer"))
+ {
+ printf("PBuffer not supported (SW engine). Skipped.\n");
+ return;
+ }
+
+ START_EVASGL_TEST(engine, NULL);
+ Evas_GL_Context *ctx;
+ Evas_GL_Surface *sfc;
+ Evas_GL_Config *cfg;
+ Evas_GL_API *gl;
+ Evas_GL *evgl;
+ unsigned int pixel;
+
+ fail_if(!(evgl = evas_gl_new(evas)));
+ fail_if(!(cfg = evas_gl_config_new()));
+ cfg->color_format = EVAS_GL_RGBA_8888;
+ fail_if(!(ctx = evas_gl_context_create(evgl, NULL)));
+ fail_if(!(sfc = evas_gl_pbuffer_surface_create(evgl, cfg, 1, 1, NULL)));
+ fail_if(!evas_gl_make_current(evgl, sfc, ctx));
+ fail_if(!(gl = evas_gl_context_api_get(evgl, ctx)));
+
+ /* clear */
+ gl->glClearColor(0, 1, 0, 1);
+ gl->glClear(GL_COLOR_BUFFER_BIT);
+ gl->glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel);
+ fail_if(gl->glGetError() != GL_NO_ERROR);
+ fail_if(pixel != 0xFF00FF00);
+
+ fail_if(!evas_gl_make_current(evgl, NULL, NULL));
+ evas_gl_context_destroy(evgl, ctx);
+ evas_gl_surface_destroy(evgl, sfc);
+ evas_gl_config_free(cfg);
evas_gl_free(evgl);
+ END_EVASGL_TEST();
+}
+
+static void
+_test_evasgl_formats(const char *engine)
+{
+ /* check that Evas GL always falls back to working surface configs */
+
+ const int options[] = { ECORE_EVAS_GL_X11_OPT_GL_DEPTH, 24,
+ ECORE_EVAS_GL_X11_OPT_GL_STENCIL, 8,
+ ECORE_EVAS_GL_X11_OPT_GL_MSAA, 4,
+ 0 };
+ const int *opts = options;
+ START_EVASGL_TEST(engine, opts);
+ Evas_GL_Context *ctx;
+ Evas_GL_Surface *sfc;
+ Evas_GL_Config *cfg;
+ Evas_GL *evgl;
+
+ fail_if(!(evgl = evas_gl_new(evas)));
+ fail_if(!(cfg = evas_gl_config_new()));
+ fail_if(!(ctx = evas_gl_context_create(evgl, NULL)));
+
+ // don't test DEPTH_32 or STENCIL_16
+ for (Evas_GL_Color_Format fmt = EVAS_GL_RGB_888; fmt < EVAS_GL_NO_FBO; fmt++)
+ for (Evas_GL_Depth_Bits depth = EVAS_GL_DEPTH_NONE; depth <= EVAS_GL_DEPTH_BIT_24; depth++)
+ for (Evas_GL_Stencil_Bits stencil = EVAS_GL_STENCIL_NONE; stencil <= EVAS_GL_STENCIL_BIT_8; stencil++)
+ for (Evas_GL_Options_Bits opt = EVAS_GL_OPTIONS_NONE; opt <= 2; opt += 2)
+ for (Evas_GL_Multisample_Bits msaa = EVAS_GL_MULTISAMPLE_NONE; msaa <= EVAS_GL_MULTISAMPLE_HIGH; msaa++)
+ {
+ cfg->color_format = fmt;
+ cfg->depth_bits = depth;
+ cfg->stencil_bits = stencil;
+ cfg->options_bits = opt;
+ cfg->multisample_bits = msaa;
+ cfg->gles_version = EVAS_GL_GLES_2_X;
+ /*
+ fprintf(stderr, "Testing surface %d %d %d %d %d\n",
+ cfg->color_format, cfg->depth_bits, cfg->stencil_bits,
+ cfg->multisample_bits, cfg->options_bits);
+ */
+ fail_if(!(sfc = evas_gl_surface_create(evgl, cfg, 1, 1)));
+ fail_if(!evas_gl_make_current(evgl, sfc, ctx));
+ fail_if(!evas_gl_make_current(evgl, NULL, NULL));
+ evas_gl_surface_destroy(evgl, sfc);
+ }
+
+ fail_if(!evas_gl_make_current(evgl, NULL, NULL));
+ evas_gl_context_destroy(evgl, ctx);
+ evas_gl_config_free(cfg);
+ evas_gl_free(evgl);
END_EVASGL_TEST();
}
-#define TEST_ADD(name) \
+#define TEST_ADD_OPT(name, opt) \
START_TEST(evas ## name ## _opengl_x11) \
- { name("opengl_x11", NULL); } \
+ { name("opengl_x11"); } \
END_TEST \
START_TEST(evas ## name ## _buffer) \
- { name("buffer", NULL); } \
+ { name("buffer"); } \
END_TEST
+#define TEST_ADD(name) TEST_ADD_OPT(name, NULL)
TEST_ADD(_test_evasgl_init)
TEST_ADD(_test_evasgl_current_get)
TEST_ADD(_test_evasgl_context_version)
TEST_ADD(_test_evasgl_surfaceless_context)
+TEST_ADD(_test_evasgl_glreadpixels)
+TEST_ADD(_test_evasgl_fbo)
+TEST_ADD(_test_evasgl_formats)
+TEST_ADD(_test_evasgl_pbuffer)
+
+/* APIs still to test:
+ *
+ * evas_gl_rotation_get
+ * evas_gl_surface_query
+ * evas_gl_error_get
+ * evas_gl_native_surface_get
+ * evas_gl_proc_address_get
+ *
+ * Most of these actually need support in SW engine to be improved.
+ */
void evas_test_evasgl(TCase *tc)
{
TEST_ADD(_test_evasgl_current_get);
TEST_ADD(_test_evasgl_context_version);
TEST_ADD(_test_evasgl_surfaceless_context);
+ TEST_ADD(_test_evasgl_glreadpixels);
+ TEST_ADD(_test_evasgl_fbo);
+ TEST_ADD(_test_evasgl_pbuffer);
+ TEST_ADD(_test_evasgl_formats);
}
#undef TEST_ADD
TEST_ADD(_test_evasgl_current_get);
TEST_ADD(_test_evasgl_context_version);
TEST_ADD(_test_evasgl_surfaceless_context);
+ TEST_ADD(_test_evasgl_glreadpixels);
+ TEST_ADD(_test_evasgl_fbo);
+ TEST_ADD(_test_evasgl_pbuffer);
+ TEST_ADD(_test_evasgl_formats);
}