aboutsummaryrefslogtreecommitdiff
path: root/render/gles2/renderer.c
diff options
context:
space:
mode:
Diffstat (limited to 'render/gles2/renderer.c')
-rw-r--r--render/gles2/renderer.c137
1 files changed, 88 insertions, 49 deletions
diff --git a/render/gles2/renderer.c b/render/gles2/renderer.c
index 9403c0ed..f96f468b 100644
--- a/render/gles2/renderer.c
+++ b/render/gles2/renderer.c
@@ -12,23 +12,27 @@
#include <wlr/render/wlr_renderer.h>
#include <wlr/types/wlr_matrix.h>
#include <wlr/util/log.h>
-#include "render/gles2.h"
#include "glapi.h"
+#include "render/gles2.h"
static const struct wlr_renderer_impl renderer_impl;
-static struct wlr_gles2_renderer *gles2_get_renderer(
+struct wlr_gles2_renderer *gles2_get_renderer(
struct wlr_renderer *wlr_renderer) {
assert(wlr_renderer->impl == &renderer_impl);
- struct wlr_gles2_renderer *renderer =
- (struct wlr_gles2_renderer *)wlr_renderer;
+ return (struct wlr_gles2_renderer *)wlr_renderer;
+}
+
+struct wlr_gles2_renderer *gles2_get_renderer_in_context(
+ struct wlr_renderer *wlr_renderer) {
+ struct wlr_gles2_renderer *renderer = gles2_get_renderer(wlr_renderer);
assert(eglGetCurrentContext() == renderer->egl->context);
return renderer;
}
static void gles2_begin(struct wlr_renderer *wlr_renderer, uint32_t width,
uint32_t height) {
- gles2_get_renderer(wlr_renderer);
+ gles2_get_renderer_in_context(wlr_renderer);
GLES2_DEBUG_PUSH;
@@ -45,13 +49,13 @@ static void gles2_begin(struct wlr_renderer *wlr_renderer, uint32_t width,
}
static void gles2_end(struct wlr_renderer *wlr_renderer) {
- gles2_get_renderer(wlr_renderer);
+ gles2_get_renderer_in_context(wlr_renderer);
// no-op
}
static void gles2_clear(struct wlr_renderer *wlr_renderer,
const float color[static 4]) {
- gles2_get_renderer(wlr_renderer);
+ gles2_get_renderer_in_context(wlr_renderer);
GLES2_DEBUG_PUSH;
glClearColor(color[0], color[1], color[2], color[3]);
@@ -61,7 +65,7 @@ static void gles2_clear(struct wlr_renderer *wlr_renderer,
static void gles2_scissor(struct wlr_renderer *wlr_renderer,
struct wlr_box *box) {
- gles2_get_renderer(wlr_renderer);
+ gles2_get_renderer_in_context(wlr_renderer);
GLES2_DEBUG_PUSH;
if (box != NULL) {
@@ -73,14 +77,6 @@ static void gles2_scissor(struct wlr_renderer *wlr_renderer,
GLES2_DEBUG_POP;
}
-static struct wlr_texture *gles2_renderer_texture_create(
- struct wlr_renderer *wlr_renderer) {
- assert(wlr_renderer->impl == &renderer_impl);
- struct wlr_gles2_renderer *renderer =
- (struct wlr_gles2_renderer *)wlr_renderer;
- return gles2_texture_create(renderer->egl);
-}
-
static void draw_quad() {
GLfloat verts[] = {
1, 0, // top right
@@ -107,21 +103,28 @@ static void draw_quad() {
glDisableVertexAttribArray(1);
}
-static bool gles2_render_texture_with_matrix(
- struct wlr_renderer *wlr_renderer, struct wlr_texture *wlr_texture,
- const float matrix[static 9], float alpha) {
- struct wlr_gles2_renderer *renderer = gles2_get_renderer(wlr_renderer);
- struct wlr_gles2_texture *texture = gles2_get_texture(wlr_texture);
- if (!wlr_texture->valid) {
- wlr_log(L_ERROR, "attempt to render invalid texture");
- return false;
- }
-
- GLuint prog = renderer->shaders.tex_rgba;
- if (texture->target == GL_TEXTURE_EXTERNAL_OES) {
+static bool gles2_render_texture_with_matrix(struct wlr_renderer *wlr_renderer,
+ struct wlr_texture *wlr_texture, const float matrix[static 9],
+ float alpha) {
+ struct wlr_gles2_renderer *renderer =
+ gles2_get_renderer_in_context(wlr_renderer);
+ struct wlr_gles2_texture *texture =
+ gles2_get_texture_in_context(wlr_texture);
+
+ GLuint prog;
+ GLenum target;
+ switch (texture->type) {
+ case WLR_GLES2_TEXTURE_GLTEX:
+ case WLR_GLES2_TEXTURE_WL_DRM_GL:
+ prog = texture->has_alpha ? renderer->shaders.tex_rgba :
+ renderer->shaders.tex_rgbx;
+ target = GL_TEXTURE_2D;
+ break;
+ case WLR_GLES2_TEXTURE_WL_DRM_EXT:
+ case WLR_GLES2_TEXTURE_DMABUF:
prog = renderer->shaders.tex_ext;
- } else if (!texture->pixel_format->has_alpha) {
- prog = renderer->shaders.tex_rgbx;
+ target = GL_TEXTURE_EXTERNAL_OES;
+ break;
}
// OpenGL ES 2 requires the glUniformMatrix3fv transpose parameter to be set
@@ -130,23 +133,32 @@ static bool gles2_render_texture_with_matrix(
wlr_matrix_transpose(transposition, matrix);
GLES2_DEBUG_PUSH;
- glBindTexture(texture->target, texture->tex_id);
- glTexParameteri(texture->target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(texture->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ GLuint tex_id = texture->type == WLR_GLES2_TEXTURE_GLTEX ?
+ texture->gl_tex : texture->image_tex;
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(target, tex_id);
+
+ glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
glUseProgram(prog);
glUniformMatrix3fv(0, 1, GL_FALSE, transposition);
- glUniform1i(1, wlr_texture->inverted_y);
+ glUniform1i(1, texture->inverted_y);
glUniform1f(3, alpha);
+
draw_quad();
+
GLES2_DEBUG_POP;
return true;
}
-static void gles2_render_quad(struct wlr_renderer *wlr_renderer,
+static void gles2_render_quad_with_matrix(struct wlr_renderer *wlr_renderer,
const float color[static 4], const float matrix[static 9]) {
- struct wlr_gles2_renderer *renderer = gles2_get_renderer(wlr_renderer);
+ struct wlr_gles2_renderer *renderer =
+ gles2_get_renderer_in_context(wlr_renderer);
// OpenGL ES 2 requires the glUniformMatrix3fv transpose parameter to be set
// to GL_FALSE
@@ -161,9 +173,10 @@ static void gles2_render_quad(struct wlr_renderer *wlr_renderer,
GLES2_DEBUG_POP;
}
-static void gles2_render_ellipse(struct wlr_renderer *wlr_renderer,
+static void gles2_render_ellipse_with_matrix(struct wlr_renderer *wlr_renderer,
const float color[static 4], const float matrix[static 9]) {
- struct wlr_gles2_renderer *renderer = gles2_get_renderer(wlr_renderer);
+ struct wlr_gles2_renderer *renderer =
+ gles2_get_renderer_in_context(wlr_renderer);
// OpenGL ES 2 requires the glUniformMatrix3fv transpose parameter to be set
// to GL_FALSE
@@ -183,20 +196,38 @@ static const enum wl_shm_format *gles2_renderer_formats(
return gles2_formats(len);
}
-static bool gles2_buffer_is_drm(struct wlr_renderer *wlr_renderer,
- struct wl_resource *buffer) {
- struct wlr_gles2_renderer *renderer = gles2_get_renderer(wlr_renderer);
+static bool gles2_resource_is_wl_drm_buffer(struct wlr_renderer *wlr_renderer,
+ struct wl_resource *resource) {
+ struct wlr_gles2_renderer *renderer =
+ gles2_get_renderer_in_context(wlr_renderer);
- EGLint format;
- return wlr_egl_query_buffer(renderer->egl, buffer, EGL_TEXTURE_FORMAT,
- &format);
+ if (!eglQueryWaylandBufferWL) {
+ return false;
+ }
+
+ EGLint fmt;
+ return eglQueryWaylandBufferWL(renderer->egl->display, resource,
+ EGL_TEXTURE_FORMAT, &fmt);
+}
+
+static void gles2_wl_drm_buffer_get_size(struct wlr_renderer *wlr_renderer,
+ struct wl_resource *buffer, int *width, int *height) {
+ struct wlr_gles2_renderer *renderer =
+ gles2_get_renderer_in_context(wlr_renderer);
+
+ if (!eglQueryWaylandBufferWL) {
+ return;
+ }
+
+ eglQueryWaylandBufferWL(renderer->egl->display, buffer, EGL_WIDTH, width);
+ eglQueryWaylandBufferWL(renderer->egl->display, buffer, EGL_HEIGHT, height);
}
static bool gles2_read_pixels(struct wlr_renderer *wlr_renderer,
enum wl_shm_format wl_fmt, uint32_t stride, uint32_t width,
uint32_t height, uint32_t src_x, uint32_t src_y, uint32_t dst_x,
uint32_t dst_y, void *data) {
- gles2_get_renderer(wlr_renderer);
+ gles2_get_renderer_in_context(wlr_renderer);
const struct gles2_pixel_format *fmt = gles2_format_from_wl(wl_fmt);
if (fmt == NULL) {
@@ -254,14 +285,17 @@ static const struct wlr_renderer_impl renderer_impl = {
.end = gles2_end,
.clear = gles2_clear,
.scissor = gles2_scissor,
- .texture_create = gles2_renderer_texture_create,
.render_texture_with_matrix = gles2_render_texture_with_matrix,
- .render_quad = gles2_render_quad,
- .render_ellipse = gles2_render_ellipse,
+ .render_quad_with_matrix = gles2_render_quad_with_matrix,
+ .render_ellipse_with_matrix = gles2_render_ellipse_with_matrix,
.formats = gles2_renderer_formats,
- .buffer_is_drm = gles2_buffer_is_drm,
+ .resource_is_wl_drm_buffer = gles2_resource_is_wl_drm_buffer,
+ .wl_drm_buffer_get_size = gles2_wl_drm_buffer_get_size,
.read_pixels = gles2_read_pixels,
.format_supported = gles2_format_supported,
+ .texture_from_pixels = gles2_texture_from_pixels,
+ .texture_from_wl_drm = gles2_texture_from_wl_drm,
+ .texture_from_dmabuf = gles2_texture_from_dmabuf,
};
void gles2_push_marker(const char *file, const char *func) {
@@ -377,6 +411,11 @@ struct wlr_renderer *wlr_gles2_renderer_create(struct wlr_backend *backend) {
renderer->egl = wlr_backend_get_egl(backend);
wlr_egl_make_current(renderer->egl, EGL_NO_SURFACE, NULL);
+ renderer->exts_str = (const char*) glGetString(GL_EXTENSIONS);
+ wlr_log(L_INFO, "Using %s", glGetString(GL_VERSION));
+ wlr_log(L_INFO, "GL vendor: %s", glGetString(GL_VENDOR));
+ wlr_log(L_INFO, "Supported GLES2 extensions: %s", renderer->exts_str);
+
if (glDebugMessageCallbackKHR && glDebugMessageControlKHR) {
glEnable(GL_DEBUG_OUTPUT_KHR);
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR);