158a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi/* 258a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi * Copyright (C) 2015 - Tobias Jakobi 358a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi * 458a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi * This is free software: you can redistribute it and/or modify 558a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi * it under the terms of the GNU General Public License as published 658a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi * by the Free Software Foundation, either version 2 of the License, 758a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi * or (at your option) any later version. 858a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi * 958a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi * It is distributed in the hope that it will be useful, but 1058a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi * WITHOUT ANY WARRANTY; without even the implied warranty of 1158a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1258a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi * GNU General Public License for more details. 1358a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi * You should have received a copy of the GNU General Public License 1458a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi * along with it. If not, see <http://www.gnu.org/licenses/>. 1558a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi */ 1658a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 1758a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi#include <unistd.h> 1858a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi#include <poll.h> 1958a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 2058a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi#include <stdlib.h> 2158a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi#include <stdio.h> 2258a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi#include <time.h> 2358a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi#include <getopt.h> 2458a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 2558a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi#include <pthread.h> 2658a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 2758a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi#include <xf86drm.h> 2858a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 2958a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi#include "exynos_drm.h" 3058a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi#include "exynos_drmif.h" 3158a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi#include "exynos_fimg2d.h" 3258a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 3358a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobistruct g2d_job { 3458a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi unsigned int id; 3558a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi unsigned int busy; 3658a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi}; 3758a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 3858a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobistruct exynos_evhandler { 3958a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi struct pollfd fds; 4058a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi struct exynos_event_context evctx; 4158a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi}; 4258a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 4358a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobistruct threaddata { 4458a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi unsigned int stop; 4558a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi struct exynos_device *dev; 4658a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi struct exynos_evhandler evhandler; 4758a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi}; 4858a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 4958a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobistatic void g2d_event_handler(int fd, unsigned int cmdlist_no, unsigned int tv_sec, 5058a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi unsigned int tv_usec, void *user_data) 5158a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi{ 5258a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi struct g2d_job *job = user_data; 5358a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 5458a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi fprintf(stderr, "info: g2d job (id = %u, cmdlist number = %u) finished!\n", 5558a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi job->id, cmdlist_no); 5658a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 5758a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi job->busy = 0; 5858a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi} 5958a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 6058a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobistatic void setup_g2d_event_handler(struct exynos_evhandler *evhandler, int fd) 6158a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi{ 6258a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi evhandler->fds.fd = fd; 6358a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi evhandler->fds.events = POLLIN; 6458a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi evhandler->evctx.base.version = 2; 6558a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi evhandler->evctx.version = 1; 6658a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi evhandler->evctx.g2d_event_handler = g2d_event_handler; 6758a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi} 6858a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 6958a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobistatic void* threadfunc(void *arg) { 7058a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi const int timeout = 0; 7158a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi struct threaddata *data; 7258a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 7358a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi data = arg; 7458a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 7558a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi while (1) { 7658a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi if (data->stop) break; 7758a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 7858a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi usleep(500); 7958a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 8058a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi data->evhandler.fds.revents = 0; 8158a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 8258a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi if (poll(&data->evhandler.fds, 1, timeout) < 0) 8358a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi continue; 8458a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 8558a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi if (data->evhandler.fds.revents & (POLLHUP | POLLERR)) 8658a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi continue; 8758a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 8858a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi if (data->evhandler.fds.revents & POLLIN) 8958a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi exynos_handle_event(data->dev, &data->evhandler.evctx); 9058a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi } 9158a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 9258a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi pthread_exit(0); 9358a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi} 9458a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 9558a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi/* 9658a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi * We need to wait until all G2D jobs are finished, otherwise we 9758a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi * potentially remove a BO which the engine still operates on. 9858a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi * This results in the following kernel message: 9958a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi * [drm:exynos_drm_gem_put_dma_addr] *ERROR* failed to lookup gem object. 10058a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi * Also any subsequent BO allocations fail then with: 10158a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi * [drm:exynos_drm_alloc_buf] *ERROR* failed to allocate buffer. 10258a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi */ 10358a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobistatic void wait_all_jobs(struct g2d_job* jobs, unsigned num_jobs) 10458a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi{ 10558a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi unsigned i; 10658a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 10758a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi for (i = 0; i < num_jobs; ++i) { 10858a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi while (jobs[i].busy) 10958a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi usleep(500); 11058a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi } 11158a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 11258a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi} 11358a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 11458a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobistatic struct g2d_job* free_job(struct g2d_job* jobs, unsigned num_jobs) 11558a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi{ 11658a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi unsigned i; 11758a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 11858a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi for (i = 0; i < num_jobs; ++i) { 11958a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi if (jobs[i].busy == 0) 12058a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi return &jobs[i]; 12158a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi } 12258a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 12358a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi return NULL; 12458a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi} 12558a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 12658a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobistatic int g2d_work(struct g2d_context *ctx, struct g2d_image *img, 12758a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi unsigned num_jobs, unsigned iterations) 12858a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi{ 12958a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi struct g2d_job *jobs = calloc(num_jobs, sizeof(struct g2d_job)); 13058a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi int ret; 13158a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi unsigned i; 13258a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 13358a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi /* setup job ids */ 13458a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi for (i = 0; i < num_jobs; ++i) 13558a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi jobs[i].id = i; 13658a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 13758a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi for (i = 0; i < iterations; ++i) { 13858a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi unsigned x, y, w, h; 13958a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 14058a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi struct g2d_job *j = NULL; 14158a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 14258a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi while (1) { 14358a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi j = free_job(jobs, num_jobs); 14458a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 14558a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi if (j) 14658a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi break; 14758a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi else 14858a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi usleep(500); 14958a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi } 15058a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 15158a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi x = rand() % img->width; 15258a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi y = rand() % img->height; 15358a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 15458a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi if (x == (img->width - 1)) 15558a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi x -= 1; 15658a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi if (y == (img->height - 1)) 15758a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi y -= 1; 15858a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 15958a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi w = rand() % (img->width - x); 16058a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi h = rand() % (img->height - y); 16158a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 16258a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi if (w == 0) w = 1; 16358a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi if (h == 0) h = 1; 16458a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 16558a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi img->color = rand(); 16658a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 16758a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi j->busy = 1; 16858a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi g2d_config_event(ctx, j); 16958a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 17058a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi ret = g2d_solid_fill(ctx, img, x, y, w, h); 17158a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 17258a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi if (ret == 0) 17358a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi g2d_exec(ctx); 17458a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 17558a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi if (ret != 0) { 17658a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi fprintf(stderr, "error: iteration %u (x = %u, x = %u, x = %u, x = %u) failed\n", 17758a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi i, x, y, w, h); 17858a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi break; 17958a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi } 18058a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi } 18158a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 18258a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi wait_all_jobs(jobs, num_jobs); 18358a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi free(jobs); 18458a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 18558a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi return 0; 18658a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi} 18758a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 18858a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobistatic void usage(const char *name) 18958a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi{ 19058a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi fprintf(stderr, "usage: %s [-ijwh]\n\n", name); 19158a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 19258a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi fprintf(stderr, "\t-i <number of iterations>\n"); 19358a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi fprintf(stderr, "\t-j <number of G2D jobs> (default = 4)\n\n"); 19458a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 19558a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi fprintf(stderr, "\t-w <buffer width> (default = 4096)\n"); 19658a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi fprintf(stderr, "\t-h <buffer height> (default = 4096)\n"); 19758a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 19858a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi exit(0); 19958a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi} 20058a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 20158a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobiint main(int argc, char **argv) 20258a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi{ 20358a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi int fd, ret, c, parsefail; 20458a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 20558a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi pthread_t event_thread; 20658a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi struct threaddata event_data = {0}; 20758a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 20858a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi struct exynos_device *dev; 20958a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi struct g2d_context *ctx; 21058a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi struct exynos_bo *bo; 21158a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 21258a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi struct g2d_image img = {0}; 21358a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 21458a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi unsigned int iters = 0, njobs = 4; 21558a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi unsigned int bufw = 4096, bufh = 4096; 21658a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 21758a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi ret = 0; 21858a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi parsefail = 0; 21958a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 22058a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi while ((c = getopt(argc, argv, "i:j:w:h:")) != -1) { 22158a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi switch (c) { 22258a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi case 'i': 22358a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi if (sscanf(optarg, "%u", &iters) != 1) 22458a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi parsefail = 1; 22558a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi break; 22658a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi case 'j': 22758a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi if (sscanf(optarg, "%u", &njobs) != 1) 22858a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi parsefail = 1; 22958a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi break; 23058a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi case 'w': 23158a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi if (sscanf(optarg, "%u", &bufw) != 1) 23258a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi parsefail = 1; 23358a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi break; 23458a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi case 'h': 23558a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi if (sscanf(optarg, "%u", &bufh) != 1) 23658a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi parsefail = 1; 23758a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi break; 23858a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi default: 23958a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi parsefail = 1; 24058a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi break; 24158a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi } 24258a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi } 24358a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 24458a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi if (parsefail || (argc == 1) || (iters == 0)) 24558a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi usage(argv[0]); 24658a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 24758a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi if (bufw > 4096 || bufh > 4096) { 24858a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi fprintf(stderr, "error: buffer width/height should be less than 4096.\n"); 24958a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi ret = -1; 25058a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 25158a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi goto out; 25258a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi } 25358a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 25458a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi if (bufw == 0 || bufh == 0) { 25558a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi fprintf(stderr, "error: buffer width/height should be non-zero.\n"); 25658a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi ret = -1; 25758a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 25858a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi goto out; 25958a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi } 26058a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 26158a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi fd = drmOpen("exynos", NULL); 26258a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi if (fd < 0) { 26358a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi fprintf(stderr, "error: failed to open drm\n"); 26458a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi ret = -1; 26558a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 26658a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi goto out; 26758a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi } 26858a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 26958a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi dev = exynos_device_create(fd); 27058a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi if (dev == NULL) { 27158a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi fprintf(stderr, "error: failed to create device\n"); 27258a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi ret = -2; 27358a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 27458a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi goto fail; 27558a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi } 27658a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 27758a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi ctx = g2d_init(fd); 27858a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi if (ctx == NULL) { 27958a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi fprintf(stderr, "error: failed to init G2D\n"); 28058a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi ret = -3; 28158a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 28258a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi goto g2d_fail; 28358a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi } 28458a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 28558a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi bo = exynos_bo_create(dev, bufw * bufh * 4, 0); 28658a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi if (bo == NULL) { 28758a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi fprintf(stderr, "error: failed to create bo\n"); 28858a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi ret = -4; 28958a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 29058a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi goto bo_fail; 29158a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi } 29258a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 29358a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi /* setup g2d image object */ 29458a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi img.width = bufw; 29558a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi img.height = bufh; 29658a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi img.stride = bufw * 4; 29758a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi img.color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB; 29858a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi img.buf_type = G2D_IMGBUF_GEM; 29958a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi img.bo[0] = bo->handle; 30058a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 30158a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi event_data.dev = dev; 30258a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi setup_g2d_event_handler(&event_data.evhandler, fd); 30358a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 30458a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi pthread_create(&event_thread, NULL, threadfunc, &event_data); 30558a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 30658a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi ret = g2d_work(ctx, &img, njobs, iters); 30758a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi if (ret != 0) 30858a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi fprintf(stderr, "error: g2d_work failed\n"); 30958a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 31058a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi event_data.stop = 1; 31158a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi pthread_join(event_thread, NULL); 31258a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 31358a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi exynos_bo_destroy(bo); 31458a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 31558a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobibo_fail: 31658a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi g2d_fini(ctx); 31758a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 31858a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobig2d_fail: 31958a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi exynos_device_destroy(dev); 32058a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 32158a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobifail: 32258a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi drmClose(fd); 32358a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi 32458a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobiout: 32558a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi return ret; 32658a39f6ba113073432dc0cd0ae702aba332c81b7Tobias Jakobi} 327