mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-04-21 06:46:46 -04:00
render: add wlr_render_timestamp
This commit is contained in:
parent
b4765809b5
commit
c38c080742
5 changed files with 146 additions and 0 deletions
|
|
@ -63,6 +63,10 @@ struct wlr_gles2_renderer {
|
||||||
PFNGLPUSHDEBUGGROUPKHRPROC glPushDebugGroupKHR;
|
PFNGLPUSHDEBUGGROUPKHRPROC glPushDebugGroupKHR;
|
||||||
PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC glEGLImageTargetRenderbufferStorageOES;
|
PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC glEGLImageTargetRenderbufferStorageOES;
|
||||||
PFNGLGETINTEGER64VEXTPROC glGetInteger64vEXT;
|
PFNGLGETINTEGER64VEXTPROC glGetInteger64vEXT;
|
||||||
|
PFNGLGENQUERIESEXTPROC glGenQueriesEXT;
|
||||||
|
PFNGLDELETEQUERIESEXTPROC glDeleteQueriesEXT;
|
||||||
|
PFNGLQUERYCOUNTEREXTPROC glQueryCounterEXT;
|
||||||
|
PFNGLGETQUERYOBJECTI64VEXTPROC glGetQueryObjecti64vEXT;
|
||||||
} procs;
|
} procs;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
|
@ -118,6 +122,12 @@ struct wlr_gles2_texture {
|
||||||
struct wlr_addon buffer_addon;
|
struct wlr_addon buffer_addon;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct wlr_gles2_timestamp {
|
||||||
|
struct wlr_render_timestamp base;
|
||||||
|
struct wlr_gles2_renderer *renderer;
|
||||||
|
GLuint query;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
bool is_gles2_pixel_format_supported(const struct wlr_gles2_renderer *renderer,
|
bool is_gles2_pixel_format_supported(const struct wlr_gles2_renderer *renderer,
|
||||||
const struct wlr_gles2_pixel_format *format);
|
const struct wlr_gles2_pixel_format *format);
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@ struct wlr_renderer_impl {
|
||||||
struct wlr_texture *(*texture_from_buffer)(struct wlr_renderer *renderer,
|
struct wlr_texture *(*texture_from_buffer)(struct wlr_renderer *renderer,
|
||||||
struct wlr_buffer *buffer);
|
struct wlr_buffer *buffer);
|
||||||
bool (*get_time)(struct wlr_renderer *r, struct timespec *t);
|
bool (*get_time)(struct wlr_renderer *r, struct timespec *t);
|
||||||
|
struct wlr_render_timestamp *(*create_timestamp)(struct wlr_renderer *r);
|
||||||
};
|
};
|
||||||
|
|
||||||
void wlr_renderer_init(struct wlr_renderer *renderer,
|
void wlr_renderer_init(struct wlr_renderer *renderer,
|
||||||
|
|
@ -63,4 +64,17 @@ struct wlr_texture_impl {
|
||||||
void wlr_texture_init(struct wlr_texture *texture,
|
void wlr_texture_init(struct wlr_texture *texture,
|
||||||
const struct wlr_texture_impl *impl, uint32_t width, uint32_t height);
|
const struct wlr_texture_impl *impl, uint32_t width, uint32_t height);
|
||||||
|
|
||||||
|
struct wlr_render_timestamp {
|
||||||
|
const struct wlr_render_timestamp_impl *impl;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct wlr_render_timestamp_impl {
|
||||||
|
void (*destroy)(struct wlr_render_timestamp *timestamp);
|
||||||
|
bool (*get_time)(struct wlr_render_timestamp *timestamp,
|
||||||
|
struct timespec *t);
|
||||||
|
};
|
||||||
|
|
||||||
|
void wlr_render_timestamp_init(struct wlr_render_timestamp *timestamp,
|
||||||
|
const struct wlr_render_timestamp_impl *impl);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,15 @@ int wlr_renderer_get_drm_fd(struct wlr_renderer *r);
|
||||||
*/
|
*/
|
||||||
bool wlr_renderer_get_time(struct wlr_renderer *r, struct timespec *t);
|
bool wlr_renderer_get_time(struct wlr_renderer *r, struct timespec *t);
|
||||||
|
|
||||||
|
struct wlr_render_timestamp;
|
||||||
|
|
||||||
|
struct wlr_render_timestamp *wlr_renderer_create_timestamp(struct wlr_renderer *r);
|
||||||
|
|
||||||
|
bool wlr_render_timestamp_get_time(struct wlr_render_timestamp *timestamp,
|
||||||
|
struct timespec *t);
|
||||||
|
|
||||||
|
void wlr_render_timestamp_destroy(struct wlr_render_timestamp *timestamp);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroys the renderer.
|
* Destroys the renderer.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -503,6 +503,35 @@ static bool gles2_get_time(struct wlr_renderer *wlr_renderer, struct timespec *t
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct wlr_render_timestamp_impl timestamp_impl;
|
||||||
|
|
||||||
|
static struct wlr_render_timestamp *gles2_create_timestamp(
|
||||||
|
struct wlr_renderer *wlr_renderer) {
|
||||||
|
struct wlr_gles2_renderer *renderer =
|
||||||
|
gles2_get_renderer_in_context(wlr_renderer);
|
||||||
|
|
||||||
|
if (!renderer->exts.EXT_disjoint_timer_query) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wlr_gles2_timestamp *timestamp = calloc(1, sizeof(*timestamp));
|
||||||
|
if (timestamp == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
wlr_render_timestamp_init(×tamp->base, ×tamp_impl);
|
||||||
|
|
||||||
|
timestamp->renderer = renderer;
|
||||||
|
|
||||||
|
GLint disjoint = 0;
|
||||||
|
push_gles2_debug(renderer);
|
||||||
|
glGetIntegerv(GL_GPU_DISJOINT_EXT, &disjoint); // clear the disjoint flag
|
||||||
|
renderer->procs.glGenQueriesEXT(1, ×tamp->query);
|
||||||
|
renderer->procs.glQueryCounterEXT(timestamp->query, GL_TIMESTAMP_EXT);
|
||||||
|
pop_gles2_debug(renderer);
|
||||||
|
|
||||||
|
return ×tamp->base;
|
||||||
|
}
|
||||||
|
|
||||||
static void gles2_destroy(struct wlr_renderer *wlr_renderer) {
|
static void gles2_destroy(struct wlr_renderer *wlr_renderer) {
|
||||||
struct wlr_gles2_renderer *renderer = gles2_get_renderer(wlr_renderer);
|
struct wlr_gles2_renderer *renderer = gles2_get_renderer(wlr_renderer);
|
||||||
|
|
||||||
|
|
@ -558,6 +587,7 @@ static const struct wlr_renderer_impl renderer_impl = {
|
||||||
.get_render_buffer_caps = gles2_get_render_buffer_caps,
|
.get_render_buffer_caps = gles2_get_render_buffer_caps,
|
||||||
.texture_from_buffer = gles2_texture_from_buffer,
|
.texture_from_buffer = gles2_texture_from_buffer,
|
||||||
.get_time = gles2_get_time,
|
.get_time = gles2_get_time,
|
||||||
|
.create_timestamp = gles2_create_timestamp,
|
||||||
};
|
};
|
||||||
|
|
||||||
void push_gles2_debug_(struct wlr_gles2_renderer *renderer,
|
void push_gles2_debug_(struct wlr_gles2_renderer *renderer,
|
||||||
|
|
@ -790,6 +820,10 @@ struct wlr_renderer *wlr_gles2_renderer_create(struct wlr_egl *egl) {
|
||||||
if (check_gl_ext(exts_str, "GL_EXT_disjoint_timer_query")) {
|
if (check_gl_ext(exts_str, "GL_EXT_disjoint_timer_query")) {
|
||||||
renderer->exts.EXT_disjoint_timer_query = true;
|
renderer->exts.EXT_disjoint_timer_query = true;
|
||||||
load_gl_proc(&renderer->procs.glGetInteger64vEXT, "glGetInteger64vEXT");
|
load_gl_proc(&renderer->procs.glGetInteger64vEXT, "glGetInteger64vEXT");
|
||||||
|
load_gl_proc(&renderer->procs.glGenQueriesEXT, "glGenQueriesEXT");
|
||||||
|
load_gl_proc(&renderer->procs.glDeleteQueriesEXT, "glDeleteQueriesEXT");
|
||||||
|
load_gl_proc(&renderer->procs.glQueryCounterEXT, "glQueryCounterEXT");
|
||||||
|
load_gl_proc(&renderer->procs.glGetQueryObjecti64vEXT, "glGetQueryObjecti64vEXT");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (renderer->exts.KHR_debug) {
|
if (renderer->exts.KHR_debug) {
|
||||||
|
|
@ -887,3 +921,56 @@ GLuint wlr_gles2_renderer_get_current_fbo(struct wlr_renderer *wlr_renderer) {
|
||||||
assert(renderer->current_buffer);
|
assert(renderer->current_buffer);
|
||||||
return renderer->current_buffer->fbo;
|
return renderer->current_buffer->fbo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct wlr_gles2_timestamp *get_timestamp(
|
||||||
|
struct wlr_render_timestamp *wlr_timestamp) {
|
||||||
|
assert(wlr_timestamp->impl == ×tamp_impl);
|
||||||
|
struct wlr_gles2_timestamp *timestamp =
|
||||||
|
wl_container_of(wlr_timestamp, timestamp, base);
|
||||||
|
return timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void timestamp_destroy(struct wlr_render_timestamp *wlr_timestamp) {
|
||||||
|
struct wlr_gles2_timestamp *timestamp = get_timestamp(wlr_timestamp);
|
||||||
|
struct wlr_gles2_renderer *renderer = timestamp->renderer;
|
||||||
|
|
||||||
|
struct wlr_egl_context prev_ctx;
|
||||||
|
wlr_egl_save_context(&prev_ctx);
|
||||||
|
wlr_egl_make_current(renderer->egl);
|
||||||
|
|
||||||
|
push_gles2_debug(renderer);
|
||||||
|
renderer->procs.glDeleteQueriesEXT(1, ×tamp->query);
|
||||||
|
pop_gles2_debug(renderer);
|
||||||
|
|
||||||
|
wlr_egl_restore_context(&prev_ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool timestamp_get_time(struct wlr_render_timestamp *wlr_timestamp,
|
||||||
|
struct timespec *t) {
|
||||||
|
struct wlr_gles2_timestamp *timestamp = get_timestamp(wlr_timestamp);
|
||||||
|
struct wlr_gles2_renderer *renderer = timestamp->renderer;
|
||||||
|
|
||||||
|
struct wlr_egl_context prev_ctx;
|
||||||
|
wlr_egl_save_context(&prev_ctx);
|
||||||
|
wlr_egl_make_current(renderer->egl);
|
||||||
|
|
||||||
|
GLint disjoint = 0;
|
||||||
|
GLint64 available = 0, nsec = 0;
|
||||||
|
push_gles2_debug(renderer);
|
||||||
|
glGetIntegerv(GL_GPU_DISJOINT_EXT, &disjoint);
|
||||||
|
renderer->procs.glGetQueryObjecti64vEXT(timestamp->query,
|
||||||
|
GL_QUERY_RESULT_AVAILABLE_EXT, &available);
|
||||||
|
renderer->procs.glGetQueryObjecti64vEXT(timestamp->query,
|
||||||
|
GL_QUERY_RESULT_EXT, &nsec);
|
||||||
|
pop_gles2_debug(renderer);
|
||||||
|
|
||||||
|
wlr_egl_restore_context(&prev_ctx);
|
||||||
|
|
||||||
|
timespec_from_nsec(t, nsec);
|
||||||
|
return available && !disjoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct wlr_render_timestamp_impl timestamp_impl = {
|
||||||
|
.destroy = timestamp_destroy,
|
||||||
|
.get_time = timestamp_get_time,
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -440,3 +440,29 @@ bool wlr_renderer_get_time(struct wlr_renderer *r, struct timespec *t) {
|
||||||
}
|
}
|
||||||
return r->impl->get_time(r, t);
|
return r->impl->get_time(r, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct wlr_render_timestamp *wlr_renderer_create_timestamp(struct wlr_renderer *r) {
|
||||||
|
if (!r->impl->create_timestamp) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return r->impl->create_timestamp(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wlr_render_timestamp_init(struct wlr_render_timestamp *timestamp,
|
||||||
|
const struct wlr_render_timestamp_impl *impl) {
|
||||||
|
assert(impl->get_time && impl->destroy);
|
||||||
|
memset(timestamp, 0, sizeof(*timestamp));
|
||||||
|
timestamp->impl = impl;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wlr_render_timestamp_get_time(struct wlr_render_timestamp *timestamp,
|
||||||
|
struct timespec *t) {
|
||||||
|
return timestamp->impl->get_time(timestamp, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wlr_render_timestamp_destroy(struct wlr_render_timestamp *timestamp) {
|
||||||
|
if (timestamp == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
timestamp->impl->destroy(timestamp);
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue