/* * Copyright (c) 2017 Rob Clark * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sub license, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include #include #include #include #include #include "common.h" #include "drm-common.h" static struct drm drm; static int offscreen_run(const struct gbm *gbm, const struct egl *egl) { struct gbm_bo *bo = NULL; uint32_t i = 0; int64_t start_time, report_time, cur_time; start_time = report_time = get_time_ns(); while (i < drm.count) { unsigned frame = i; struct gbm_bo *next_bo; /* Start fps measuring on second frame, to remove the time spent * compiling shader, etc, from the fps: */ if (i == 1) { start_time = report_time = get_time_ns(); } if (!gbm->surface) { glBindFramebuffer(GL_FRAMEBUFFER, egl->fbs[frame % NUM_BUFFERS].fb); } egl->draw(i++); if (gbm->surface) { eglSwapBuffers(egl->display, egl->surface); next_bo = gbm_surface_lock_front_buffer(gbm->surface); } else { glFinish(); next_bo = gbm->bos[frame % NUM_BUFFERS]; } if (!next_bo) { printf("Failed to lock frontbuffer\n"); return -1; } cur_time = get_time_ns(); if (cur_time > (report_time + 2 * NSEC_PER_SEC)) { double elapsed_time = cur_time - start_time; double secs = elapsed_time / (double)NSEC_PER_SEC; unsigned frames = i - 1; /* first frame ignored */ printf("Rendered %u frames in %f sec (%f fps)\n", frames, secs, (double)frames/secs); report_time = cur_time; } /* release last buffer to render on again: */ if (bo && gbm->surface) gbm_surface_release_buffer(gbm->surface, bo); bo = next_bo; } finish_perfcntrs(); cur_time = get_time_ns(); double elapsed_time = cur_time - start_time; double secs = elapsed_time / (double)NSEC_PER_SEC; unsigned frames = i - 1; /* first frame ignored */ printf("Rendered %u frames in %f sec (%f fps)\n", frames, secs, (double)frames/secs); dump_perfcntrs(frames, elapsed_time); return 0; } const struct drm * init_drm_offscreen(const char *device, const char *mode_str, unsigned int count) { int ret; ret = init_drm_render(&drm, device, mode_str, count); if (ret) return NULL; drm.run = offscreen_run; return &drm; }