From 8d50744ceb140019b805ed1b246194300e41a5f1 Mon Sep 17 00:00:00 2001
From: Tomi Valkeinen <tomi.valkeinen@ti.com>
Date: Wed, 25 May 2016 17:30:07 +0300
Subject: parallelize drawing of test pattern

---
 libkms++util/CMakeLists.txt |  2 +-
 libkms++util/testpat.cpp    | 38 +++++++++++++++++++++++++++++++++-----
 2 files changed, 34 insertions(+), 6 deletions(-)

diff --git a/libkms++util/CMakeLists.txt b/libkms++util/CMakeLists.txt
index d08ec84..533b446 100644
--- a/libkms++util/CMakeLists.txt
+++ b/libkms++util/CMakeLists.txt
@@ -1,5 +1,5 @@
 file(GLOB SRCS "*.cpp" "*.h")
 add_library(kms++util ${SRCS})
 
-target_link_libraries(kms++util kms++)
+target_link_libraries(kms++util kms++ pthread)
 target_include_directories(kms++util PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/libkms++util/testpat.cpp b/libkms++util/testpat.cpp
index cee6e85..7a15a35 100644
--- a/libkms++util/testpat.cpp
+++ b/libkms++util/testpat.cpp
@@ -4,6 +4,7 @@
 #include <chrono>
 #include <cstring>
 #include <cassert>
+#include <thread>
 
 #include <kms++.h>
 #include <kms++util.h>
@@ -11,6 +12,8 @@
 
 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
 
+using namespace std;
+
 namespace kms
 {
 static void draw_rgb_pixel(IMappedFramebuffer& buf, unsigned x, unsigned y, RGB color)
@@ -209,11 +212,10 @@ static RGB get_test_pattern_pixel(IMappedFramebuffer& fb, unsigned x, unsigned y
 	}
 }
 
-static void draw_test_pattern_impl(IMappedFramebuffer& fb)
+static void draw_test_pattern_part(IMappedFramebuffer& fb, unsigned start_y, unsigned end_y)
 {
 	unsigned x, y;
 	unsigned w = fb.width();
-	unsigned h = fb.height();
 
 	switch (fb.format()) {
 	case PixelFormat::XRGB8888:
@@ -221,7 +223,7 @@ static void draw_test_pattern_impl(IMappedFramebuffer& fb)
 	case PixelFormat::ARGB8888:
 	case PixelFormat::ABGR8888:
 	case PixelFormat::RGB565:
-		for (y = 0; y < h; y++) {
+		for (y = start_y; y < end_y; y++) {
 			for (x = 0; x < w; x++) {
 				RGB pixel = get_test_pattern_pixel(fb, x, y);
 				draw_rgb_pixel(fb, x, y, pixel);
@@ -233,7 +235,7 @@ static void draw_test_pattern_impl(IMappedFramebuffer& fb)
 	case PixelFormat::YUYV:
 	case PixelFormat::YVYU:
 	case PixelFormat::VYUY:
-		for (y = 0; y < h; y++) {
+		for (y = start_y; y < end_y; y++) {
 			for (x = 0; x < w; x += 2) {
 				RGB pixel1 = get_test_pattern_pixel(fb, x, y);
 				RGB pixel2 = get_test_pattern_pixel(fb, x + 1, y);
@@ -244,7 +246,7 @@ static void draw_test_pattern_impl(IMappedFramebuffer& fb)
 
 	case PixelFormat::NV12:
 	case PixelFormat::NV21:
-		for (y = 0; y < h; y += 2) {
+		for (y = start_y; y < end_y; y += 2) {
 			for (x = 0; x < w; x += 2) {
 				RGB pixel00 = get_test_pattern_pixel(fb, x, y);
 				RGB pixel10 = get_test_pattern_pixel(fb, x + 1, y);
@@ -261,6 +263,32 @@ static void draw_test_pattern_impl(IMappedFramebuffer& fb)
 	}
 }
 
+static void draw_test_pattern_impl(IMappedFramebuffer& fb)
+{
+	if (fb.height() < 20) {
+		draw_test_pattern_part(fb, 0, fb.height());
+		return;
+	}
+
+	unsigned num_threads = thread::hardware_concurrency();
+	vector<thread> workers;
+
+	unsigned part = (fb.height() / num_threads) & ~1;
+
+	for (unsigned n = 0; n < num_threads; ++n) {
+		unsigned start = n * part;
+		unsigned end = start + part;
+
+		if (n == num_threads - 1)
+			end = fb.height();
+
+		workers.push_back(thread([&fb, start, end]() { draw_test_pattern_part(fb, start, end); }));
+	}
+
+	for (thread& t : workers)
+		t.join();
+}
+
 void draw_test_pattern(IMappedFramebuffer &fb)
 {
 #ifdef DRAW_PERF_PRINT
-- 
cgit v1.2.3