diff --git a/.github/workflows/depends.yml b/.github/workflows/depends.yml new file mode 100644 index 000000000..7b7eabb84 --- /dev/null +++ b/.github/workflows/depends.yml @@ -0,0 +1,54 @@ +################################################################################ +# This workflow will do a clean install of node dependencies, build the source +# code and run tests across different versions of node. +# +# For more information see: +# +# https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions +# +################################################################################ + +name: Node.js CI + +# Controls when the action will run. Triggers the workflow on push or pull +# request events +on: [push, pull_request] + +# A workflow run is made up of one or more jobs that can run sequentially or in +# parallel +jobs: + # This workflow contains a single job called "build" + build: + # The type of runner that the job will run on + runs-on: ${{ matrix.os }} + + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-20.04 + - os: ubuntu-22.04 + + # Steps represent a sequence of tasks that will be executed as part of the + # job + steps: + - name: Build environment information + run: 'echo "Matrix OS: ${{ matrix.os }} on $HOSTNAME with $(getconf _NPROCESSORS_ONLN) cores"' + + # Check-out the repository under $GITHUB_WORKSPACE, so the job can + # access it + - name: Checkout main repo + uses: actions/checkout@v4 + + - name: Restore dependency build files + id: restore-depends + uses: actions/cache@v3 + with: + path: | + src/generated + tools/dist + key: restore-library-depends-${{ matrix.os }}-${{ hashFiles('tools/depends/ade/*', 'tools/depends/ceres-solver/*', 'tools/depends/eigen/*', 'tools/depends/emscripten/*', 'tools/depends/google-flags/*', 'tools/depends/google-log/*', 'tools/depends/opencv/*') }} + + - name: Build depends + if: steps.restore-depends.outputs.cache-hit != 'true' + run: tools/npm-depends.sh all diff --git a/.gitignore b/.gitignore index d59374df1..96fc2d984 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +# Generated dependencies +/src/generated + # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] diff --git a/tools/.gitignore b/tools/.gitignore new file mode 100644 index 000000000..a4ac49a6b --- /dev/null +++ b/tools/.gitignore @@ -0,0 +1,11 @@ +# Dependency build files +build/ + +# Installed dependency files +dist/ + +# Dependency repos +repos/ + +# Build system stamps +stamps/ diff --git a/tools/Makefile b/tools/Makefile new file mode 100644 index 000000000..e63fbe358 --- /dev/null +++ b/tools/Makefile @@ -0,0 +1,167 @@ +################################################################################ +# +# Copyright (C) 2020-2023 retro.ai +# This file is part of retro-dapp - https://github.com/RetroAI/retro-dapp +# +# SPDX-License-Identifier: Apache-2.0 +# See the file LICENSE.txt for more information. +# +################################################################################ + +################################################################################ +# +# Build chain for dependendies +# +# Make is used to run shell commands instead of bash to allow for parallel +# intermediary build stages. +# +# The primary build stages that can be specified on the command line are: +# +# 1. checkout +# 2. patch +# 3. build +# 4. install (default if no stage is given) +# +# Two stages are used for cleaning temoprary files: +# +# 1. clean +# 2. distclean +# +# "make clean" is used to remove temporary build artifacts. "make distclean" is +# used to remove all temporary files and reset the directory to an unused state. +# +# This Makefile depends on the following packages: +# +# - curl +# - patch +# - python3 +# - unzip +# +################################################################################ + +# Build system setup +include setup_stages.mk +include setup_paths.mk + +# Build parameter setup +include setup_environment.mk + +# Define the shell used to execute commands +SHELL := /bin/bash + +################################################################################ +# +# Import package rules +# +################################################################################ + +include depends/ade/package.mk +include depends/android-sdk/package.mk +include depends/ceres-solver/package.mk +include depends/eigen/package.mk +include depends/emscripten/package.mk +include depends/google-flags/package.mk +include depends/google-log/package.mk +include depends/opencv/package.mk + +################################################################################ +# +# Build system targets +# +# Defines the targets that are build when "make" is run. +# +################################################################################ + +# +# Define targets for "make checkout" +# + +CHECKOUT_DEPENDS = \ + $(S)/checkout-ade \ + $(S)/checkout-ceres \ + $(S)/checkout-eigen \ + $(S)/checkout-emsdk \ + $(S)/checkout-gflags \ + $(S)/checkout-glog \ + $(S)/checkout-opencv \ + $(S)/patch-opencv + +ifeq ($(PLATFORM),darwin) + #CHECKOUT_DEPENDS += $(S)/checkout-android-sdk # TODO +endif + +# +# Define targets for "make build" +# + +BUILD_DEPENDS = \ + $(S)/build-opencv \ + +# +# Define targets for "make install" +# + +INSTALL_DEPENDS = \ + $(S)/install-opencv \ + +# +# Inject targets +# + +checkout: $(CHECKOUT_DEPENDS) +build: $(BUILD_DEPENDS) +install: $(INSTALL_DEPENDS) + +# +# Define targets for building individual depends via "make " +# + +.PHONY: ade +.PHONY: ceres +.PHONY: eigen +.PHONY: emscripten +.PHONY: gflags +.PHONY: glog +.PHONY: opencv + +ade: \ + $(S)/install-ade + +ceres: \ + $(S)/install-ceres + +eigen: \ + $(S)/install-eigen + +emscripten: \ + $(S)/build-emsdk + +gflags: \ + $(S)/install-gflags + +glog: \ + $(S)/install-glog + +opencv: \ + $(S)/install-opencv + +################################################################################ +# +# Build system procedures +# +################################################################################ + +# +# Clean stage +# + +clean: + rm -rf "$(BUILD_DIR)" + rm -rf "$(S)" + +# +# Distclean stage +# + +distclean: clean + rm -rf "$(REPO_DIR)" diff --git a/tools/depends/ade/package.mk b/tools/depends/ade/package.mk new file mode 100644 index 000000000..1f09c9f6c --- /dev/null +++ b/tools/depends/ade/package.mk @@ -0,0 +1,114 @@ +################################################################################ +# +# Copyright (C) 2020-2023 retro.ai +# This file is part of retro-dapp - https://github.com/RetroAI/retro-dapp +# +# SPDX-License-Identifier: Apache-2.0 +# See the file LICENSE.txt for more information. +# +################################################################################ + +################################################################################ +# +# ADE Framework +# +# The ADE Framework is a graph construction, manipulation, and processing +# framework. ADE Framework is suitable for organizing data flow processing and +# execution. +# +# SPDX-License-Identifier: Apache-2.0 +# +################################################################################ + +# Dependency name and version +ADE_REPO_NAME = ade +ADE_VERSION = 0.1.1f +ADE_REMOTE_REPO = https://github.com/opencv/$(ADE_REPO_NAME).git +ADE_LIB = libade.a + +################################################################################ +# +# Paths +# +################################################################################ + +# Checkout directory +REPO_DIR_ADE = $(REPO_DIR)/$(ADE_REPO_NAME) + +# Build directory +BUILD_DIR_ADE = $(BUILD_DIR)/$(ADE_REPO_NAME) + +# Build output +BUILD_FILE_ADE = $(BUILD_DIR_ADE)/lib/$(ADE_LIB) + +# Install output +INSTALL_FILE_ADE = $(DEPENDS_DIR)/lib/$(ADE_LIB) + +################################################################################ +# +# Configuration +# +################################################################################ + +ADE_BUILD_DEPENDS = \ + $(S)/checkout-ade \ + $(S)/build-emsdk \ + +################################################################################ +# +# Checkout +# +################################################################################ + +$(S)/checkout-ade: $(S)/.precheckout + [ -d "$(REPO_DIR_ADE)" ] || ( \ + git clone -b v$(ADE_VERSION) "$(ADE_REMOTE_REPO)" "$(REPO_DIR_ADE)" \ + ) + + @# TODO: Repository sync is delegated to the CI system. + + touch "$@" + +################################################################################ +# +# Build +# +################################################################################ + +$(BUILD_FILE_ADE): $(S)/.prebuild $(ADE_BUILD_DEPENDS) + mkdir -p "$(BUILD_DIR_ADE)" + + # Activate PATH and other environment variables in the current terminal and + # build ADE + . "$(REPO_DIR_EMSDK)/emsdk_set_env.sh" && \ + cd "${BUILD_DIR_ADE}" && \ + emcmake cmake "$(REPO_DIR_ADE)" \ + -DCMAKE_INSTALL_PREFIX="$(DEPENDS_DIR)" \ + -DCMAKE_BUILD_PARALLEL_LEVEL=$(shell getconf _NPROCESSORS_ONLN) \ + $(shell ! command -v ccache &> /dev/null || echo "-DCMAKE_CXX_COMPILER_LAUNCHER=ccache") \ + + #cmake --build "${BUILD_DIR_ADE}" + make -C "${BUILD_DIR_ADE}" -j$(shell getconf _NPROCESSORS_ONLN) + + touch "$@" + +$(S)/build-ade: $(BUILD_FILE_ADE) + touch "$@" + +################################################################################ +# +# Install +# +################################################################################ + +$(INSTALL_FILE_ADE): $(S)/.preinstall $(S)/build-ade + mkdir -p "$(DEPENDS_DIR)" + + cmake \ + --build "${BUILD_DIR_ADE}" \ + --target install + + touch "$@" + +$(S)/install-ade: $(INSTALL_FILE_ADE) + touch "$@" diff --git a/tools/depends/android-sdk/package.mk b/tools/depends/android-sdk/package.mk new file mode 100644 index 000000000..dc53fac78 --- /dev/null +++ b/tools/depends/android-sdk/package.mk @@ -0,0 +1,53 @@ +################################################################################ +# +# Copyright (C) 2020-2023 retro.ai +# This file is part of retro-dapp - https://github.com/RetroAI/retro-dapp +# +# SPDX-License-Identifier: Apache-2.0 +# See the file LICENSE.txt for more information. +# +################################################################################ + +################################################################################ +# +# Andriod SDK +# +# The Android SDK contains a version of CMake and Ninja. +# +# Not currently used, but could be helpful in a restricted environment where +# you can't install these yourself. +# +################################################################################ + +################################################################################ +# +# Paths +# +################################################################################ + +# Checkout directory +REPO_DIR_ANDROID_SDK = $(REPO_DIR)/android-sdk + +################################################################################ +# +# Checkout +# +################################################################################ + +$(S)/checkout-android-sdk: $(S)/.precheckout + mkdir -p "$(REPO_DIR_ANDROID_SDK)" + + [ -f "$(REPO_DIR)/android-sdk-macos-4.0.zip" ] || \ + curl --silent "https://dl.google.com/android/repository/commandlinetools-mac-6609375_latest.zip" \ + > "$(REPO_DIR)/android-sdk-macos-4.0.zip" + + unzip -q -n "$(REPO_DIR)/android-sdk-macos-4.0.zip" \ + -d "$(REPO_DIR_ANDROID_SDK)" + + cd "$(REPO_DIR_ANDROID_SDK)/tools/bin" && \ + yes | ./sdkmanager --sdk_root="`pwd`/../.." --licenses && \ + ./sdkmanager --sdk_root="`pwd`/../.." platform-tools && \ + ./sdkmanager --sdk_root="`pwd`/../.." "platforms;android-28" && \ + ./sdkmanager --sdk_root="`pwd`/../.." "build-tools;28.0.3" + + touch "$@" diff --git a/tools/depends/ceres-solver/package.mk b/tools/depends/ceres-solver/package.mk new file mode 100644 index 000000000..904aa6c03 --- /dev/null +++ b/tools/depends/ceres-solver/package.mk @@ -0,0 +1,127 @@ +################################################################################ +# +# Copyright (C) 2020-2023 retro.ai +# This file is part of retro-dapp - https://github.com/RetroAI/retro-dapp +# +# SPDX-License-Identifier: Apache-2.0 +# See the file LICENSE.txt for more information. +# +################################################################################ + +################################################################################ +# +# Ceres Solver +# +# Ceres Solver is an open source C++ library for modeling and solving large, +# complicated optimization problems. +# +# Ceres Solver can solve two kinds of problems. +# +# 1. Non-linear Least Squares problems with bounds constraints +# 2. General unconstrained optimization problems +# +# SPDX-License-Identifier: BSD-3-Clause +# +################################################################################ + +# Dependency name and version +CERES_REPO_NAME = ceres-solver +CERES_VERSION = 1.14.0 +CERES_REMOTE_REPO = https://github.com/ceres-solver/$(CERES_REPO_NAME).git +CERES_LIB = libceres.a + +################################################################################ +# +# Paths +# +################################################################################ + +# Checkout directory +REPO_DIR_CERES = $(REPO_DIR)/$(CERES_REPO_NAME) + +# Build directory +BUILD_DIR_CERES = $(BUILD_DIR)/$(CERES_REPO_NAME) + +# Build output +BUILD_FILE_CERES = $(BUILD_DIR_CERES)/lib/$(CERES_LIB) + +# Install output +INSTALL_FILE_CERES = $(DEPENDS_DIR)/lib/$(CERES_LIB) + +################################################################################ +# +# Configuration +# +################################################################################ + +CERES_BUILD_DEPENDS = \ + $(S)/checkout-ceres \ + $(S)/build-emsdk \ + $(S)/install-gflags \ + $(S)/install-glog \ + $(S)/install-eigen \ + +################################################################################ +# +# Checkout +# +################################################################################ + +$(S)/checkout-ceres: $(S)/.precheckout + [ -d "$(REPO_DIR_CERES)" ] || ( \ + git clone -b $(CERES_VERSION) "$(CERES_REMOTE_REPO)" "$(REPO_DIR_CERES)" \ + ) + + @# TODO: Repository sync is delegated to the CI system. + + touch "$@" + +################################################################################ +# +# Build +# +################################################################################ + +$(BUILD_FILE_CERES): $(S)/.prebuild $(CERES_BUILD_DEPENDS) + mkdir -p "$(BUILD_DIR_CERES)" + + # Activate PATH and other environment variables in the current terminal and + # build ceres + . "$(REPO_DIR_EMSDK)/emsdk_set_env.sh" && \ + cd "${BUILD_DIR_CERES}" && \ + emcmake cmake "$(REPO_DIR_CERES)" \ + -DCMAKE_FIND_ROOT_PATH="$(DEPENDS_DIR)" \ + -DCMAKE_INSTALL_PREFIX="$(DEPENDS_DIR)" \ + -DCMAKE_BUILD_PARALLEL_LEVEL=$(shell getconf _NPROCESSORS_ONLN) \ + -DBUILD_TESTING=OFF \ + -DBUILD_EXAMPLES=OFF \ + -DBUILD_BENCHMARKS=OFF \ + $(shell ! command -v ccache &> /dev/null || echo "-DCMAKE_CXX_COMPILER_LAUNCHER=ccache") \ + + # Rebuilding takes a long time + [ -f "$(BUILD_FILE_CERES)" ] || ( \ + make -C "${BUILD_DIR_CERES}" -j$(shell getconf _NPROCESSORS_ONLN) \ + ) + + touch "$@" + +$(S)/build-ceres: $(BUILD_FILE_CERES) + touch "$@" + +################################################################################ +# +# Install +# +################################################################################ + +$(INSTALL_FILE_CERES): $(S)/.preinstall $(S)/build-ceres + mkdir -p "$(DEPENDS_DIR)" + + cmake \ + --build "${BUILD_DIR_CERES}" \ + --target install + + touch "$@" + +$(S)/install-ceres: $(INSTALL_FILE_CERES) + touch "$@" diff --git a/tools/depends/eigen/package.mk b/tools/depends/eigen/package.mk new file mode 100644 index 000000000..2309f481e --- /dev/null +++ b/tools/depends/eigen/package.mk @@ -0,0 +1,104 @@ +################################################################################ +# +# Copyright (C) 2020-2023 retro.ai +# This file is part of retro-dapp - https://github.com/RetroAI/retro-dapp +# +# SPDX-License-Identifier: Apache-2.0 +# See the file LICENSE.txt for more information. +# +################################################################################ + +################################################################################ +# +# Eigen +# +# Eigen is a C++ template library for linear algebra: matrices, vectors, +# numerical solvers, and related algorithms. +# +# SPDX-License-Identifier: BSD-3-Clause +# +################################################################################ + +# Dependency name and version +EIGEN_REPO_NAME = eigen +EIGEN_VERSION = 3.3.7 +EIGEN_REMOTE_REPO = https://gitlab.com/libeigen/$(EIGEN_REPO_NAME).git +EIGEN_HEADER = Matrix.h + +################################################################################ +# +# Paths +# +################################################################################ + +# Checkout directory +REPO_DIR_EIGEN = $(REPO_DIR)/$(EIGEN_REPO_NAME) + +# Build directory +BUILD_DIR_EIGEN = $(BUILD_DIR)/$(EIGEN_REPO_NAME) + +# Install output +INSTALL_FILE_EIGEN = $(DEPENDS_DIR)/include/eigen3/Eigen/src/Core/$(EIGEN_HEADER) + +################################################################################ +# +# Configuration +# +################################################################################ + +EIGEN_BUILD_DEPENDS = \ + $(S)/checkout-eigen \ + $(S)/build-emsdk + +################################################################################ +# +# Checkout +# +################################################################################ + +$(S)/checkout-eigen: $(S)/.precheckout + [ -d "$(REPO_DIR_EIGEN)" ] || git clone -b $(EIGEN_VERSION) "$(EIGEN_REMOTE_REPO)" "$(REPO_DIR_EIGEN)" + + @# TODO: Repository sync is delegated to the CI system. + + touch "$@" + +################################################################################ +# +# Build +# +################################################################################ + +$(S)/build-eigen: $(S)/.prebuild $(EIGEN_BUILD_DEPENDS) + mkdir -p "$(BUILD_DIR_EIGEN)" + + # Activate PATH and other environment variables in the current terminal and + # build eigen + . "$(REPO_DIR_EMSDK)/emsdk_set_env.sh" && \ + cd "${BUILD_DIR_EIGEN}" && \ + emcmake cmake "$(REPO_DIR_EIGEN)" \ + -DCMAKE_INSTALL_PREFIX="$(DEPENDS_DIR)" \ + -DCMAKE_BUILD_PARALLEL_LEVEL=$(shell getconf _NPROCESSORS_ONLN) \ + $(shell ! command -v ccache &> /dev/null || echo "-DCMAKE_CXX_COMPILER_LAUNCHER=ccache") \ + + cmake --build "${BUILD_DIR_EIGEN}" + + touch "$@" + +################################################################################ +# +# Install +# +################################################################################ + +$(INSTALL_FILE_EIGEN): $(S)/.preinstall $(S)/build-eigen + mkdir -p "$(DEPENDS_DIR)" + + cmake \ + --build "${BUILD_DIR_EIGEN}" \ + --target install + + touch "$@" + +$(S)/install-eigen: $(INSTALL_FILE_EIGEN) + touch "$@" diff --git a/tools/depends/emscripten/package.mk b/tools/depends/emscripten/package.mk new file mode 100644 index 000000000..994c25e04 --- /dev/null +++ b/tools/depends/emscripten/package.mk @@ -0,0 +1,70 @@ +################################################################################ +# +# Copyright (C) 2020-2023 retro.ai +# This file is part of retro-dapp - https://github.com/RetroAI/retro-dapp +# +# SPDX-License-Identifier: Apache-2.0 +# See the file LICENSE.txt for more information. +# +################################################################################ + +################################################################################ +# +# Emscripten SDK +# +# The Emscripten toolchain is distributed as a standalone Emscripten SDK. The +# SDK provides required tools, such as Clang, Python and Node.js. +# +# SPDX-License-Identifier: MIT +# +################################################################################ + +# Dependency name and version +EMSDK_REPO_NAME = emsdk +EMSDK_VERSION = 1.39.18 +EMSDK_SDK_TOOLS_VERSION = latest-upstream +EMSDK_REMOTE_REPO = https://github.com/emscripten-core/$(EMSDK_REPO_NAME).git +EMSDK_BINARY = emsdk + +################################################################################ +# +# Paths +# +################################################################################ + +# Checkout directory +REPO_DIR_EMSDK = $(REPO_DIR)/$(EMSDK_REPO_NAME) + +################################################################################ +# +# Checkout +# +################################################################################ + +$(S)/checkout-emsdk: $(S)/.precheckout + [ -d "$(REPO_DIR_EMSDK)" ] || git clone -b $(EMSDK_VERSION) "$(EMSDK_REMOTE_REPO)" "$(REPO_DIR_EMSDK)" + + @# TODO: Repository sync is delegated to the CI system. + + # Download and install the latest SDK tools. + cd "$(REPO_DIR_EMSDK)" && \ + "$(REPO_DIR_EMSDK)/emsdk" install --build=Release --shallow $(EMSDK_SDK_TOOLS_VERSION) + + touch "$@" + +################################################################################ +# +# Build +# +################################################################################ + +$(S)/build-emsdk: $(S)/.prebuild $(S)/checkout-emsdk + # Make SDK "active" for the current user (writes .emscripten file) + cd "$(REPO_DIR_EMSDK)" && \ + "$(REPO_DIR_EMSDK)/emsdk" activate $(EMSDK_SDK_TOOLS_VERSION) + + # Create an evironment setup script + cd "$(REPO_DIR_EMSDK)" && \ + "$(REPO_DIR_EMSDK)/emsdk" construct_env + + touch "$@" diff --git a/tools/depends/google-flags/package.mk b/tools/depends/google-flags/package.mk new file mode 100644 index 000000000..aa0b4557b --- /dev/null +++ b/tools/depends/google-flags/package.mk @@ -0,0 +1,113 @@ +################################################################################ +# +# Copyright (C) 2020-2023 retro.ai +# This file is part of retro-dapp - https://github.com/RetroAI/retro-dapp +# +# SPDX-License-Identifier: Apache-2.0 +# See the file LICENSE.txt for more information. +# +################################################################################ + +################################################################################ +# +# gflags +# +# The gflags package contains a C++ library that implements commandline flags +# processing. +# +# SPDX-License-Identifier: BSD-3-Clause +# +################################################################################ + +# Dependency name and version +GFLAGS_REPO_NAME = gflags +GFLAGS_VERSION = 2.2.2 +GFLAGS_REMOTE_REPO = https://github.com/gflags/$(GFLAGS_REPO_NAME).git +GFLAGS_LIB = libgflags.a + +################################################################################ +# +# Paths +# +################################################################################ + +# Checkout directory +REPO_DIR_GFLAGS = $(REPO_DIR)/$(GFLAGS_REPO_NAME) + +# Build directory +BUILD_DIR_GFLAGS = $(BUILD_DIR)/$(GFLAGS_REPO_NAME) + +# Build output +BUILD_FILE_GFLAGS = $(BUILD_DIR_GFLAGS)/lib/$(GFLAGS_LIB) + +# Install output +INSTALL_FILE_GFLAGS = $(DEPENDS_DIR)/lib/$(GFLAGS_LIB) + +################################################################################ +# +# Configuration +# +################################################################################ + +GFLAGS_BUILD_DEPENDS = \ + $(S)/checkout-gflags \ + $(S)/build-emsdk + +################################################################################ +# +# Checkout +# +################################################################################ + +$(S)/checkout-gflags: $(S)/.precheckout + [ -d "$(REPO_DIR_GFLAGS)" ] || ( \ + git clone -b v$(GFLAGS_VERSION) "$(GFLAGS_REMOTE_REPO)" "$(REPO_DIR_GFLAGS)" \ + ) + + @# TODO: Repository sync is delegated to the CI system. + + touch "$@" + +################################################################################ +# +# Build +# +################################################################################ + +$(BUILD_FILE_GFLAGS): $(S)/.prebuild $(GFLAGS_BUILD_DEPENDS) + mkdir -p "$(BUILD_DIR_GFLAGS)" + + # Activate PATH and other environment variables in the current terminal and + # build gflags + . "$(REPO_DIR_EMSDK)/emsdk_set_env.sh" && \ + cd "${BUILD_DIR_GFLAGS}" && \ + emcmake cmake "$(REPO_DIR_GFLAGS)" \ + -DCMAKE_INSTALL_PREFIX="$(DEPENDS_DIR)" \ + -DCMAKE_BUILD_PARALLEL_LEVEL=$(shell getconf _NPROCESSORS_ONLN) \ + $(shell ! command -v ccache &> /dev/null || echo "-DCMAKE_CXX_COMPILER_LAUNCHER=ccache") \ + + #cmake --build "${BUILD_DIR_GFLAGS}" + make -C "${BUILD_DIR_GFLAGS}" -j$(shell getconf _NPROCESSORS_ONLN) + + touch "$@" + +$(S)/build-gflags: $(BUILD_FILE_GFLAGS) + touch "$@" + +################################################################################ +# +# Install +# +################################################################################ + +$(INSTALL_FILE_GFLAGS): $(S)/.preinstall $(S)/build-gflags + mkdir -p "$(DEPENDS_DIR)" + + cmake \ + --build "${BUILD_DIR_GFLAGS}" \ + --target install + + touch "$@" + +$(S)/install-gflags: $(INSTALL_FILE_GFLAGS) + touch "$@" diff --git a/tools/depends/google-log/0001-Disable-syscalls-for-Emscripten.patch b/tools/depends/google-log/0001-Disable-syscalls-for-Emscripten.patch new file mode 100644 index 000000000..1004ac9ca --- /dev/null +++ b/tools/depends/google-log/0001-Disable-syscalls-for-Emscripten.patch @@ -0,0 +1,32 @@ +From abad2b770a0fe28b51ac07827be7a80c4bb32475 Mon Sep 17 00:00:00 2001 +Date: Wed, 29 Jul 2020 09:12:25 -0700 +Subject: [PATCH 1/3] Disable syscalls for Emscripten + +Fixes error: + + src/raw_logging.cc:139:3: error: use of undeclared identifier 'syscall' + safe_write(STDERR_FILENO, buffer, strlen(buffer)); + ^ +--- + CMakeLists.txt | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 808330e..d1cb98a 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -72,11 +72,9 @@ check_include_file (stdlib.h HAVE_STDLIB_H) + check_include_file (string.h HAVE_STRING_H) + check_include_file (strings.h HAVE_STRINGS_H) + check_include_file (sys/stat.h HAVE_SYS_STAT_H) +-check_include_file (sys/syscall.h HAVE_SYS_SYSCALL_H) + check_include_file (sys/time.h HAVE_SYS_TIME_H) + check_include_file (sys/types.h HAVE_SYS_TYPES_H) + check_include_file (sys/utsname.h HAVE_SYS_UTSNAME_H) +-check_include_file (syscall.h HAVE_SYSCALL_H) + check_include_file (syslog.h HAVE_SYSLOG_H) + check_include_file (ucontext.h HAVE_UCONTEXT_H) + check_include_file (unistd.h HAVE_UNISTD_H) +-- +2.17.1 + diff --git a/tools/depends/google-log/0002-Disable-symbolize-for-Emscripten.patch b/tools/depends/google-log/0002-Disable-symbolize-for-Emscripten.patch new file mode 100644 index 000000000..6b8471669 --- /dev/null +++ b/tools/depends/google-log/0002-Disable-symbolize-for-Emscripten.patch @@ -0,0 +1,29 @@ +From acd68cb48a898a50ab3d6dd0b0c646dd7918e064 Mon Sep 17 00:00:00 2001 +Date: Wed, 29 Jul 2020 09:33:35 -0700 +Subject: [PATCH 2/3] Disable symbolize for Emscripten + +Fixes error: + + src/symbolize.cc:931:10: error: use of undeclared identifier 'SymbolizeAndDemangle' + return SymbolizeAndDemangle(pc, out, out_size); + ^ +--- + CMakeLists.txt | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index d1cb98a..6420a40 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -388,8 +388,6 @@ if (WIN32 OR CYGWIN) + if (HAVE_SYMBOLIZE) + set (HAVE_STACKTRACE 1) + endif (HAVE_SYMBOLIZE) +-elseif (UNIX OR (APPLE AND HAVE_DLADDR)) +- set (HAVE_SYMBOLIZE 1) + endif (WIN32 OR CYGWIN) + + check_cxx_source_compiles (" +-- +2.17.1 + diff --git a/tools/depends/google-log/0003-Remove-email-code-for-Emscripten.patch b/tools/depends/google-log/0003-Remove-email-code-for-Emscripten.patch new file mode 100644 index 000000000..a125860ef --- /dev/null +++ b/tools/depends/google-log/0003-Remove-email-code-for-Emscripten.patch @@ -0,0 +1,35 @@ +From 5a8a767ab6f3f59440151195d8b881ad625e6465 Mon Sep 17 00:00:00 2001 +Date: Wed, 29 Jul 2020 09:46:44 -0700 +Subject: [PATCH 3/3] Remove email code for Emscripten + +Fixes error: + + error: undefined symbol: popen (referenced by top-level compiled C/C++ code) +--- + src/logging.cc | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/logging.cc b/src/logging.cc +index 0c86cf6..23a5074 100644 +--- a/src/logging.cc ++++ b/src/logging.cc +@@ -1792,6 +1792,8 @@ static string ShellEscape(const string& src) { + // log_mutex. + static bool SendEmailInternal(const char*dest, const char *subject, + const char*body, bool use_logging) { ++// popen not defined for Emscripten ++#if 0 + if (dest && *dest) { + if ( use_logging ) { + VLOG(1) << "Trying to send TITLE:" << subject +@@ -1830,6 +1832,7 @@ static bool SendEmailInternal(const char*dest, const char *subject, + } + } + } ++#endif + return false; + } + +-- +2.17.1 + diff --git a/tools/depends/google-log/package.mk b/tools/depends/google-log/package.mk new file mode 100644 index 000000000..693f0f4bc --- /dev/null +++ b/tools/depends/google-log/package.mk @@ -0,0 +1,132 @@ +################################################################################ +# +# Copyright (C) 2020-2023 retro.ai +# This file is part of retro-dapp - https://github.com/RetroAI/retro-dapp +# +# SPDX-License-Identifier: Apache-2.0 +# See the file LICENSE.txt for more information. +# +################################################################################ + +################################################################################ +# +# Google Logging Library +# +# The Google Logging Library (glog) implements application-level logging. +# The library provides logging APIs based on C++-style streams and various +# helper macros. +# +# SPDX-License-Identifier: BSD-3-Clause +# +################################################################################ + +# Dependency name and version +GLOG_REPO_NAME = glog +GLOG_VERSION = 0.4.0 +GLOG_REMOTE_REPO = https://github.com/google/$(GLOG_REPO_NAME).git +GLOG_LIB = libglog.a + +################################################################################ +# +# Paths +# +################################################################################ + +# Checkout directory +REPO_DIR_GLOG = $(REPO_DIR)/$(GLOG_REPO_NAME) + +# Build directory +BUILD_DIR_GLOG = $(BUILD_DIR)/$(GLOG_REPO_NAME) + +# Build output +BUILD_FILE_GLOG = $(BUILD_DIR_GLOG)/$(GLOG_LIB) + +# Install output +INSTALL_FILE_GLOG = $(DEPENDS_DIR)/lib/$(GLOG_LIB) + +################################################################################ +# +# Configuration +# +################################################################################ + +GLOG_BUILD_DEPENDS = \ + $(S)/checkout-glog \ + $(S)/build-emsdk \ + $(S)/install-gflags \ + +################################################################################ +# +# Checkout +# +################################################################################ + +$(S)/checkout-glog: $(S)/.precheckout \ + $(TOOL_DIR)/depends/google-log/0001-Disable-syscalls-for-Emscripten.patch \ + $(TOOL_DIR)/depends/google-log/0002-Disable-symbolize-for-Emscripten.patch \ + $(TOOL_DIR)/depends/google-log/0003-Remove-email-code-for-Emscripten.patch + [ -d "$(REPO_DIR_GLOG)" ] || ( \ + git clone -b v$(GLOG_VERSION) "$(GLOG_REMOTE_REPO)" "$(REPO_DIR_GLOG)" \ + ) + + @# TODO: Repository sync is delegated to the CI system. + + patch -p1 --forward --directory="$(REPO_DIR_GLOG)" < \ + "$(TOOL_DIR)/depends/google-log/0001-Disable-syscalls-for-Emscripten.patch" || ( \ + code=$$?; [[ "$${code}" -lt "2" ]] || exit $${code}; \ + ) + + patch -p1 --forward --directory="$(REPO_DIR_GLOG)" < \ + "$(TOOL_DIR)/depends/google-log/0002-Disable-symbolize-for-Emscripten.patch" || ( \ + code=$$?; [[ "$${code}" -lt "2" ]] || exit $${code}; \ + ) + + patch -p1 --forward --directory="$(REPO_DIR_GLOG)" < \ + "$(TOOL_DIR)/depends/google-log/0003-Remove-email-code-for-Emscripten.patch" || ( \ + code=$$?; [[ "$${code}" -lt "2" ]] || exit $${code}; \ + ) + + touch "$@" + +################################################################################ +# +# Build +# +################################################################################ + +$(BUILD_FILE_GLOG): $(S)/.prebuild $(GLOG_BUILD_DEPENDS) + mkdir -p "$(BUILD_DIR_GLOG)" + + # Activate PATH and other environment variables in the current terminal and + # build glog + . "$(REPO_DIR_EMSDK)/emsdk_set_env.sh" && \ + cd "${BUILD_DIR_GLOG}" && \ + emcmake cmake "$(REPO_DIR_GLOG)" \ + -DCMAKE_FIND_ROOT_PATH="$(DEPENDS_DIR)" \ + -DCMAKE_INSTALL_PREFIX="$(DEPENDS_DIR)" \ + $(shell ! command -v ccache &> /dev/null || echo "-DCMAKE_CXX_COMPILER_LAUNCHER=ccache") \ + + cmake --build "${BUILD_DIR_GLOG}" + + touch "$@" + +$(S)/build-glog: $(BUILD_FILE_GLOG) + touch "$@" + +################################################################################ +# +# Install +# +################################################################################ + +$(INSTALL_FILE_GLOG): $(S)/.preinstall $(S)/build-glog + mkdir -p "$(DEPENDS_DIR)" + + cmake \ + --build "${BUILD_DIR_GLOG}" \ + --target install + + touch "$@" + +$(S)/install-glog: $(INSTALL_FILE_GLOG) + touch "$@" diff --git a/tools/depends/opencv/0001-Fix-sfm-disabled-when-Eigen-is-present.patch b/tools/depends/opencv/0001-Fix-sfm-disabled-when-Eigen-is-present.patch new file mode 100644 index 000000000..a17d3b952 --- /dev/null +++ b/tools/depends/opencv/0001-Fix-sfm-disabled-when-Eigen-is-present.patch @@ -0,0 +1,27 @@ +From 19319182a827563702424d4e597cd9bb25aba554 Mon Sep 17 00:00:00 2001 +Date: Wed, 29 Jul 2020 10:16:24 -0700 +Subject: [PATCH] Fix sfm disabled when Eigen is present + +Fixes error: + +-- Module opencv_sfm disabled because the following dependencies are not found: Eigen +--- + modules/sfm/CMakeLists.txt | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/modules/sfm/CMakeLists.txt b/modules/sfm/CMakeLists.txt +index 53a8d437..38b03b0a 100644 +--- a/modules/sfm/CMakeLists.txt ++++ b/modules/sfm/CMakeLists.txt +@@ -9,6 +9,8 @@ find_package(Ceres QUIET) + if(NOT Ceres_FOUND) # Looks like Ceres find glog on the own, so separate search isn't necessary + find_package(Glog QUIET) + endif() ++find_package(Eigen3 QUIET REQUIRED) ++set(HAVE_EIGEN 1) + + if((gflags_FOUND OR GFLAGS_FOUND OR GFLAGS_INCLUDE_DIRS) AND (glog_FOUND OR GLOG_FOUND OR GLOG_INCLUDE_DIRS)) + set(_fname "${CMAKE_CURRENT_BINARY_DIR}/test_sfm_deps.cpp") +-- +2.17.1 + diff --git a/tools/depends/opencv/0001-GAPI-Implement-RGBA2Gray-and-GBRA2Gray.patch b/tools/depends/opencv/0001-GAPI-Implement-RGBA2Gray-and-GBRA2Gray.patch new file mode 100644 index 000000000..97bd4ccb3 --- /dev/null +++ b/tools/depends/opencv/0001-GAPI-Implement-RGBA2Gray-and-GBRA2Gray.patch @@ -0,0 +1,770 @@ +From 4bd65501cf4bb5dd8484057aaaba3d69dfaf9f2e Mon Sep 17 00:00:00 2001 +Date: Mon, 19 Oct 2020 01:27:35 -0700 +Subject: [PATCH] GAPI: Implement RGBA2Gray and GBRA2Gray + +--- + modules/gapi/include/opencv2/gapi/imgproc.hpp | 40 ++++++++++ + .../perf/common/gapi_imgproc_perf_tests.hpp | 2 + + .../common/gapi_imgproc_perf_tests_inl.hpp | 76 +++++++++++++++++++ + .../perf/cpu/gapi_imgproc_perf_tests_cpu.cpp | 10 +++ + .../cpu/gapi_imgproc_perf_tests_fluid.cpp | 10 +++ + .../perf/gpu/gapi_imgproc_perf_tests_gpu.cpp | 10 +++ + modules/gapi/src/api/kernels_imgproc.cpp | 10 +++ + modules/gapi/src/backends/cpu/gcpuimgproc.cpp | 18 +++++ + .../gapi/src/backends/fluid/gfluidimgproc.cpp | 49 +++++++++++- + .../fluid/gfluidimgproc_func.dispatch.cpp | 14 ++++ + .../src/backends/fluid/gfluidimgproc_func.hpp | 9 +++ + .../fluid/gfluidimgproc_func.simd.hpp | 46 +++++++++++ + modules/gapi/src/backends/ocl/goclimgproc.cpp | 18 +++++ + .../gapi/test/common/gapi_imgproc_tests.hpp | 2 + + .../test/common/gapi_imgproc_tests_inl.hpp | 38 ++++++++++ + .../gapi/test/cpu/gapi_imgproc_tests_cpu.cpp | 16 ++++ + .../test/cpu/gapi_imgproc_tests_fluid.cpp | 16 ++++ + .../gapi/test/gpu/gapi_imgproc_tests_gpu.cpp | 16 ++++ + 18 files changed, 399 insertions(+), 1 deletion(-) + +diff --git a/modules/gapi/include/opencv2/gapi/imgproc.hpp b/modules/gapi/include/opencv2/gapi/imgproc.hpp +index 294b3b7842..f92283ad86 100644 +--- a/modules/gapi/include/opencv2/gapi/imgproc.hpp ++++ b/modules/gapi/include/opencv2/gapi/imgproc.hpp +@@ -240,6 +240,12 @@ namespace imgproc { + } + }; + ++ G_TYPED_KERNEL(GRGBA2Gray, , "org.opencv.imgproc.colorconvert.rgba2gray") { ++ static GMatDesc outMeta(GMatDesc in) { ++ return in.withType(CV_8U, 1); ++ } ++ }; ++ + G_TYPED_KERNEL(GRGB2GrayCustom, , "org.opencv.imgproc.colorconvert.rgb2graycustom") { + static GMatDesc outMeta(GMatDesc in, float, float, float) { + return in.withType(CV_8U, 1); +@@ -252,6 +258,12 @@ namespace imgproc { + } + }; + ++ G_TYPED_KERNEL(GBGRA2Gray, , "org.opencv.imgproc.colorconvert.bgra2gray") { ++ static GMatDesc outMeta(GMatDesc in) { ++ return in.withType(CV_8U, 1); ++ } ++ }; ++ + G_TYPED_KERNEL(GBayerGR2RGB, , "org.opencv.imgproc.colorconvert.bayergr2rgb") { + static cv::GMatDesc outMeta(cv::GMatDesc in) { + return in.withType(CV_8U, 3); +@@ -884,6 +896,22 @@ Resulting gray color value computed as + */ + GAPI_EXPORTS GMat RGB2Gray(const GMat& src); + ++//! @} gapi_filters ++ ++//! @addtogroup gapi_colorconvert ++//! @{ ++/** @brief Converts an image from RGBA color space to gray-scaled. ++The conventional ranges for R, G, and B channel values are 0 to 255. ++Resulting gray color value computed as ++\f[\texttt{dst} (I)= \texttt{0.299} * \texttt{src}(I).R + \texttt{0.587} * \texttt{src}(I).G + \texttt{0.114} * \texttt{src}(I).B \f] ++ ++@note Function textual ID is "org.opencv.imgproc.colorconvert.rgb2gray" ++ ++@param src input image: 8-bit unsigned 4-channel image @ref CV_8UC1. ++@sa RGB2YUV ++ */ ++GAPI_EXPORTS GMat RGBA2Gray(const GMat& src); ++ + /** @overload + Resulting gray color value computed as + \f[\texttt{dst} (I)= \texttt{rY} * \texttt{src}(I).R + \texttt{gY} * \texttt{src}(I).G + \texttt{bY} * \texttt{src}(I).B \f] +@@ -910,6 +938,18 @@ Resulting gray color value computed as + */ + GAPI_EXPORTS GMat BGR2Gray(const GMat& src); + ++/** @brief Converts an image from BGRA color space to gray-scaled. ++The conventional ranges for B, G, and R channel values are 0 to 255. ++Resulting gray color value computed as ++\f[\texttt{dst} (I)= \texttt{0.114} * \texttt{src}(I).B + \texttt{0.587} * \texttt{src}(I).G + \texttt{0.299} * \texttt{src}(I).R \f] ++ ++@note Function textual ID is "org.opencv.imgproc.colorconvert.bgr2gray" ++ ++@param src input image: 8-bit unsigned 4-channel image @ref CV_8UC1. ++@sa BGR2LUV ++ */ ++GAPI_EXPORTS GMat BGRA2Gray(const GMat& src); ++ + /** @brief Converts an image from RGB color space to YUV color space. + + The function converts an input image from RGB color space to YUV. +diff --git a/modules/gapi/perf/common/gapi_imgproc_perf_tests.hpp b/modules/gapi/perf/common/gapi_imgproc_perf_tests.hpp +index b2591907cf..035f57aa02 100644 +--- a/modules/gapi/perf/common/gapi_imgproc_perf_tests.hpp ++++ b/modules/gapi/perf/common/gapi_imgproc_perf_tests.hpp +@@ -43,7 +43,9 @@ class GoodFeaturesPerfTest : public TestPerfParams> {}; + class EqHistPerfTest : public TestPerfParams> {}; + class RGB2GrayPerfTest : public TestPerfParams> {}; ++class RGBA2GrayPerfTest : public TestPerfParams> {}; + class BGR2GrayPerfTest : public TestPerfParams> {}; ++class BGRA2GrayPerfTest : public TestPerfParams> {}; + class RGB2YUVPerfTest : public TestPerfParams> {}; + class YUV2RGBPerfTest : public TestPerfParams> {}; + class RGB2LabPerfTest : public TestPerfParams> {}; +diff --git a/modules/gapi/perf/common/gapi_imgproc_perf_tests_inl.hpp b/modules/gapi/perf/common/gapi_imgproc_perf_tests_inl.hpp +index f71e435a2b..223f36d6c9 100644 +--- a/modules/gapi/perf/common/gapi_imgproc_perf_tests_inl.hpp ++++ b/modules/gapi/perf/common/gapi_imgproc_perf_tests_inl.hpp +@@ -826,6 +826,44 @@ PERF_TEST_P_(RGB2GrayPerfTest, TestPerformance) + + //------------------------------------------------------------------------------ + ++PERF_TEST_P_(RGBA2GrayPerfTest, TestPerformance) ++{ ++ compare_f cmpF = get<0>(GetParam()); ++ Size sz = get<1>(GetParam()); ++ cv::GCompileArgs compile_args = get<2>(GetParam()); ++ ++ initMatrixRandN(CV_8UC4, sz, CV_8UC1, false); ++ ++ // OpenCV code ///////////////////////////////////////////////////////////// ++ { ++ cv::cvtColor(in_mat1, out_mat_ocv, cv::COLOR_RGBA2GRAY); ++ } ++ ++ // G-API code ////////////////////////////////////////////////////////////// ++ cv::GMat in; ++ auto out = cv::gapi::RGBA2Gray(in); ++ cv::GComputation c(in, out); ++ ++ // Warm-up graph engine: ++ c.apply(in_mat1, out_mat_gapi, std::move(compile_args)); ++ ++ TEST_CYCLE() ++ { ++ c.apply(in_mat1, out_mat_gapi); ++ } ++ ++ // Comparison ////////////////////////////////////////////////////////////// ++ { ++ EXPECT_TRUE(cmpF(out_mat_gapi, out_mat_ocv)); ++ EXPECT_EQ(out_mat_gapi.size(), sz); ++ } ++ ++ SANITY_CHECK_NOTHING(); ++ ++} ++ ++//------------------------------------------------------------------------------ ++ + PERF_TEST_P_(BGR2GrayPerfTest, TestPerformance) + { + compare_f cmpF = get<0>(GetParam()); +@@ -864,6 +902,44 @@ PERF_TEST_P_(BGR2GrayPerfTest, TestPerformance) + + //------------------------------------------------------------------------------ + ++PERF_TEST_P_(BGRA2GrayPerfTest, TestPerformance) ++{ ++ compare_f cmpF = get<0>(GetParam()); ++ Size sz = get<1>(GetParam()); ++ cv::GCompileArgs compile_args = get<2>(GetParam()); ++ ++ initMatrixRandN(CV_8UC4, sz, CV_8UC1, false); ++ ++ // OpenCV code ///////////////////////////////////////////////////////////// ++ { ++ cv::cvtColor(in_mat1, out_mat_ocv, cv::COLOR_BGRA2GRAY); ++ } ++ ++ // G-API code ////////////////////////////////////////////////////////////// ++ cv::GMat in; ++ auto out = cv::gapi::BGRA2Gray(in); ++ cv::GComputation c(in, out); ++ ++ // Warm-up graph engine: ++ c.apply(in_mat1, out_mat_gapi, std::move(compile_args)); ++ ++ TEST_CYCLE() ++ { ++ c.apply(in_mat1, out_mat_gapi); ++ } ++ ++ // Comparison ////////////////////////////////////////////////////////////// ++ { ++ EXPECT_TRUE(cmpF(out_mat_gapi, out_mat_ocv)); ++ EXPECT_EQ(out_mat_gapi.size(), sz); ++ } ++ ++ SANITY_CHECK_NOTHING(); ++ ++} ++ ++//------------------------------------------------------------------------------ ++ + PERF_TEST_P_(RGB2YUVPerfTest, TestPerformance) + { + compare_f cmpF = get<0>(GetParam()); +diff --git a/modules/gapi/perf/cpu/gapi_imgproc_perf_tests_cpu.cpp b/modules/gapi/perf/cpu/gapi_imgproc_perf_tests_cpu.cpp +index 4de1b18308..ebda2ac3b1 100644 +--- a/modules/gapi/perf/cpu/gapi_imgproc_perf_tests_cpu.cpp ++++ b/modules/gapi/perf/cpu/gapi_imgproc_perf_tests_cpu.cpp +@@ -184,11 +184,21 @@ INSTANTIATE_TEST_CASE_P(RGB2GrayPerfTestCPU, RGB2GrayPerfTest, + Values(szVGA, sz720p, sz1080p), + Values(cv::compile_args(IMGPROC_CPU)))); + ++INSTANTIATE_TEST_CASE_P(RGBA2GrayPerfTestCPU, RGBA2GrayPerfTest, ++ Combine(Values(AbsExact().to_compare_f()), ++ Values(szVGA, sz720p, sz1080p), ++ Values(cv::compile_args(IMGPROC_CPU)))); ++ + INSTANTIATE_TEST_CASE_P(BGR2GrayPerfTestCPU, BGR2GrayPerfTest, + Combine(Values(AbsExact().to_compare_f()), + Values(szVGA, sz720p, sz1080p), + Values(cv::compile_args(IMGPROC_CPU)))); + ++INSTANTIATE_TEST_CASE_P(BGRA2GrayPerfTestCPU, BGRA2GrayPerfTest, ++ Combine(Values(AbsExact().to_compare_f()), ++ Values(szVGA, sz720p, sz1080p), ++ Values(cv::compile_args(IMGPROC_CPU)))); ++ + INSTANTIATE_TEST_CASE_P(RGB2YUVPerfTestCPU, RGB2YUVPerfTest, + Combine(Values(AbsExact().to_compare_f()), + Values(szVGA, sz720p, sz1080p), +diff --git a/modules/gapi/perf/cpu/gapi_imgproc_perf_tests_fluid.cpp b/modules/gapi/perf/cpu/gapi_imgproc_perf_tests_fluid.cpp +index 1ccd763099..0d96ce212d 100644 +--- a/modules/gapi/perf/cpu/gapi_imgproc_perf_tests_fluid.cpp ++++ b/modules/gapi/perf/cpu/gapi_imgproc_perf_tests_fluid.cpp +@@ -148,11 +148,21 @@ INSTANTIATE_TEST_CASE_P(RGB2GrayPerfTestFluid, RGB2GrayPerfTest, + Values(szVGA, sz720p, sz1080p), + Values(cv::compile_args(IMGPROC_FLUID)))); + ++INSTANTIATE_TEST_CASE_P(RGBA2GrayPerfTestFluid, RGBA2GrayPerfTest, ++ Combine(Values(ToleranceColor(1e-3).to_compare_f()), ++ Values(szVGA, sz720p, sz1080p), ++ Values(cv::compile_args(IMGPROC_FLUID)))); ++ + INSTANTIATE_TEST_CASE_P(BGR2GrayPerfTestFluid, BGR2GrayPerfTest, + Combine(Values(ToleranceColor(1e-3).to_compare_f()), + Values(szVGA, sz720p, sz1080p), + Values(cv::compile_args(IMGPROC_FLUID)))); + ++INSTANTIATE_TEST_CASE_P(BGRA2GrayPerfTestFluid, BGRA2GrayPerfTest, ++ Combine(Values(ToleranceColor(1e-3).to_compare_f()), ++ Values(szVGA, sz720p, sz1080p), ++ Values(cv::compile_args(IMGPROC_FLUID)))); ++ + INSTANTIATE_TEST_CASE_P(RGB2YUVPerfTestFluid, RGB2YUVPerfTest, + Combine(Values(ToleranceColor(1e-3).to_compare_f()), + Values(szVGA, sz720p, sz1080p), +diff --git a/modules/gapi/perf/gpu/gapi_imgproc_perf_tests_gpu.cpp b/modules/gapi/perf/gpu/gapi_imgproc_perf_tests_gpu.cpp +index 1f4f3883d1..2b5fdcf19b 100644 +--- a/modules/gapi/perf/gpu/gapi_imgproc_perf_tests_gpu.cpp ++++ b/modules/gapi/perf/gpu/gapi_imgproc_perf_tests_gpu.cpp +@@ -164,11 +164,21 @@ INSTANTIATE_TEST_CASE_P(RGB2GrayPerfTestGPU, RGB2GrayPerfTest, + Values(szVGA, sz720p, sz1080p), + Values(cv::compile_args(IMGPROC_GPU)))); + ++INSTANTIATE_TEST_CASE_P(RGBA2GrayPerfTestGPU, RGBA2GrayPerfTest, ++ Combine(Values(ToleranceColor(1e-3).to_compare_f()), ++ Values(szVGA, sz720p, sz1080p), ++ Values(cv::compile_args(IMGPROC_GPU)))); ++ + INSTANTIATE_TEST_CASE_P(BGR2GrayPerfTestGPU, BGR2GrayPerfTest, + Combine(Values(ToleranceColor(1e-3).to_compare_f()), + Values(szVGA, sz720p, sz1080p), + Values(cv::compile_args(IMGPROC_GPU)))); + ++INSTANTIATE_TEST_CASE_P(BGRA2GrayPerfTestGPU, BGRA2GrayPerfTest, ++ Combine(Values(ToleranceColor(1e-3).to_compare_f()), ++ Values(szVGA, sz720p, sz1080p), ++ Values(cv::compile_args(IMGPROC_GPU)))); ++ + INSTANTIATE_TEST_CASE_P(RGB2YUVPerfTestGPU, RGB2YUVPerfTest, + Combine(Values(ToleranceColor(1e-3).to_compare_f()), + Values(szVGA, sz720p, sz1080p), +diff --git a/modules/gapi/src/api/kernels_imgproc.cpp b/modules/gapi/src/api/kernels_imgproc.cpp +index 652f83935f..1d980b36a2 100644 +--- a/modules/gapi/src/api/kernels_imgproc.cpp ++++ b/modules/gapi/src/api/kernels_imgproc.cpp +@@ -130,11 +130,21 @@ GMat RGB2Gray(const GMat& src, float rY, float gY, float bY) + return imgproc::GRGB2GrayCustom::on(src, rY, gY, bY); + } + ++GMat RGBA2Gray(const GMat& src) ++{ ++ return imgproc::GRGBA2Gray::on(src); ++} ++ + GMat BGR2Gray(const GMat& src) + { + return imgproc::GBGR2Gray::on(src); + } + ++GMat BGRA2Gray(const GMat& src) ++{ ++ return imgproc::GBGRA2Gray::on(src); ++} ++ + GMat RGB2YUV(const GMat& src) + { + return imgproc::GRGB2YUV::on(src); +diff --git a/modules/gapi/src/backends/cpu/gcpuimgproc.cpp b/modules/gapi/src/backends/cpu/gcpuimgproc.cpp +index c07ed6785c..f25e6f5c9c 100644 +--- a/modules/gapi/src/backends/cpu/gcpuimgproc.cpp ++++ b/modules/gapi/src/backends/cpu/gcpuimgproc.cpp +@@ -331,6 +331,14 @@ GAPI_OCV_KERNEL(GCPURGB2Gray, cv::gapi::imgproc::GRGB2Gray) + } + }; + ++GAPI_OCV_KERNEL(GCPURGBA2Gray, cv::gapi::imgproc::GRGBA2Gray) ++{ ++ static void run(const cv::Mat& in, cv::Mat &out) ++ { ++ cv::cvtColor(in, out, cv::COLOR_RGBA2GRAY); ++ } ++}; ++ + GAPI_OCV_KERNEL(GCPUBGR2Gray, cv::gapi::imgproc::GBGR2Gray) + { + static void run(const cv::Mat& in, cv::Mat &out) +@@ -339,6 +347,14 @@ GAPI_OCV_KERNEL(GCPUBGR2Gray, cv::gapi::imgproc::GBGR2Gray) + } + }; + ++GAPI_OCV_KERNEL(GCPUBGRA2Gray, cv::gapi::imgproc::GBGRA2Gray) ++{ ++ static void run(const cv::Mat& in, cv::Mat &out) ++ { ++ cv::cvtColor(in, out, cv::COLOR_BGRA2GRAY); ++ } ++}; ++ + GAPI_OCV_KERNEL(GCPURGB2GrayCustom, cv::gapi::imgproc::GRGB2GrayCustom) + { + static void run(const cv::Mat& in, float rY, float bY, float gY, cv::Mat &out) +@@ -500,7 +516,9 @@ cv::gapi::GKernelPackage cv::gapi::imgproc::cpu::kernels() + , GCPUYUV2BGR + , GCPULUV2BGR + , GCPUBGR2Gray ++ , GCPUBGRA2Gray + , GCPURGB2Gray ++ , GCPURGBA2Gray + , GCPURGB2GrayCustom + , GCPUBayerGR2RGB + , GCPURGB2HSV +diff --git a/modules/gapi/src/backends/fluid/gfluidimgproc.cpp b/modules/gapi/src/backends/fluid/gfluidimgproc.cpp +index 7ddf91e122..4cc34a9064 100644 +--- a/modules/gapi/src/backends/fluid/gfluidimgproc.cpp ++++ b/modules/gapi/src/backends/fluid/gfluidimgproc.cpp +@@ -37,7 +37,7 @@ namespace fluid { + + //---------------------------------- + // +-// Fluid kernels: RGB2Gray, BGR2Gray ++// Fluid kernels: RGB2Gray, BGR2Gray, RGB2AGray, BGRA2Gray + // + //---------------------------------- + +@@ -70,6 +70,25 @@ static void run_rgb2gray(Buffer &dst, const View &src, float coef_r, float coef_ + run_rgb2gray_impl(out, in, width, coef_r, coef_g, coef_b); + } + ++static void run_rgba2gray(Buffer &dst, const View &src, float coef_r, float coef_g, float coef_b) ++{ ++ GAPI_Assert(src.meta().depth == CV_8U); ++ GAPI_Assert(dst.meta().depth == CV_8U); ++ GAPI_Assert(src.meta().chan == 4); ++ GAPI_Assert(dst.meta().chan == 1); ++ GAPI_Assert(src.length() == dst.length()); ++ ++ GAPI_Assert(coef_r < 1 && coef_g < 1 && coef_b < 1); ++ GAPI_Assert(std::abs(coef_r + coef_g + coef_b - 1) < 0.001); ++ ++ const auto *in = src.InLine(0); ++ auto *out = dst.OutLine(); ++ ++ int width = dst.length(); ++ ++ run_rgba2gray_impl(out, in, width, coef_r, coef_g, coef_b); ++} ++ + GAPI_FLUID_KERNEL(GFluidRGB2GrayCustom, cv::gapi::imgproc::GRGB2GrayCustom, false) + { + static const int Window = 1; +@@ -93,6 +112,19 @@ GAPI_FLUID_KERNEL(GFluidRGB2Gray, cv::gapi::imgproc::GRGB2Gray, false) + } + }; + ++GAPI_FLUID_KERNEL(GFluidRGBA2Gray, cv::gapi::imgproc::GRGBA2Gray, false) ++{ ++ static const int Window = 1; ++ ++ static void run(const View &src, Buffer &dst) ++ { ++ float coef_r = coef_rgb2yuv_bt601[0]; ++ float coef_g = coef_rgb2yuv_bt601[1]; ++ float coef_b = coef_rgb2yuv_bt601[2]; ++ run_rgba2gray(dst, src, coef_r, coef_g, coef_b); ++ } ++}; ++ + GAPI_FLUID_KERNEL(GFluidBGR2Gray, cv::gapi::imgproc::GBGR2Gray, false) + { + static const int Window = 1; +@@ -106,6 +138,19 @@ GAPI_FLUID_KERNEL(GFluidBGR2Gray, cv::gapi::imgproc::GBGR2Gray, false) + } + }; + ++GAPI_FLUID_KERNEL(GFluidBGRA2Gray, cv::gapi::imgproc::GBGRA2Gray, false) ++{ ++ static const int Window = 1; ++ ++ static void run(const View &src, Buffer &dst) ++ { ++ float coef_r = coef_rgb2yuv_bt601[0]; ++ float coef_g = coef_rgb2yuv_bt601[1]; ++ float coef_b = coef_rgb2yuv_bt601[2]; ++ run_rgba2gray(dst, src, coef_b, coef_g, coef_r); ++ } ++}; ++ + //-------------------------------------- + // + // Fluid kernels: RGB-to-YUV, YUV-to-RGB +@@ -1831,7 +1876,9 @@ cv::gapi::GKernelPackage cv::gapi::imgproc::fluid::kernels() + + return cv::gapi::kernels + < GFluidBGR2Gray ++ , GFluidBGRA2Gray + , GFluidRGB2Gray ++ , GFluidRGBA2Gray + , GFluidRGB2GrayCustom + , GFluidRGB2YUV + , GFluidYUV2RGB +diff --git a/modules/gapi/src/backends/fluid/gfluidimgproc_func.dispatch.cpp b/modules/gapi/src/backends/fluid/gfluidimgproc_func.dispatch.cpp +index 7854d3e988..1775763d08 100644 +--- a/modules/gapi/src/backends/fluid/gfluidimgproc_func.dispatch.cpp ++++ b/modules/gapi/src/backends/fluid/gfluidimgproc_func.dispatch.cpp +@@ -41,6 +41,20 @@ void run_rgb2gray_impl(uchar out[], const uchar in[], int width, + CV_CPU_DISPATCH_MODES_ALL); + } + ++//---------------------------------- ++// ++// Fluid kernels: RGBA2Gray, BGRA2Gray ++// ++//---------------------------------- ++ ++void run_rgba2gray_impl(uchar out[], const uchar in[], int width, ++ float coef_r, float coef_g, float coef_b) ++{ ++ CV_CPU_DISPATCH(run_rgba2gray_impl, ++ (out, in, width, coef_r, coef_g, coef_b), ++ CV_CPU_DISPATCH_MODES_ALL); ++} ++ + //-------------------------------------- + // + // Fluid kernels: RGB-to-HSV +diff --git a/modules/gapi/src/backends/fluid/gfluidimgproc_func.hpp b/modules/gapi/src/backends/fluid/gfluidimgproc_func.hpp +index 79715d1754..00b521fc50 100644 +--- a/modules/gapi/src/backends/fluid/gfluidimgproc_func.hpp ++++ b/modules/gapi/src/backends/fluid/gfluidimgproc_func.hpp +@@ -23,6 +23,15 @@ namespace fluid { + void run_rgb2gray_impl(uchar out[], const uchar in[], int width, + float coef_r, float coef_g, float coef_b); + ++//---------------------------------- ++// ++// Fluid kernels: RGBA2Gray, BGRA2Gray ++// ++//---------------------------------- ++ ++void run_rgba2gray_impl(uchar out[], const uchar in[], int width, ++ float coef_r, float coef_g, float coef_b); ++ + //-------------------------------------- + // + // Fluid kernels: RGB-to-HSV +diff --git a/modules/gapi/src/backends/fluid/gfluidimgproc_func.simd.hpp b/modules/gapi/src/backends/fluid/gfluidimgproc_func.simd.hpp +index 9766cf7cc6..0ab68fd373 100644 +--- a/modules/gapi/src/backends/fluid/gfluidimgproc_func.simd.hpp ++++ b/modules/gapi/src/backends/fluid/gfluidimgproc_func.simd.hpp +@@ -45,6 +45,15 @@ CV_CPU_OPTIMIZATION_NAMESPACE_BEGIN + void run_rgb2gray_impl(uchar out[], const uchar in[], int width, + float coef_r, float coef_g, float coef_b); + ++//---------------------------------- ++// ++// Fluid kernels: RGBA2Gray, BGRA2Gray ++// ++//---------------------------------- ++ ++void run_rgba2gray_impl(uchar out[], const uchar in[], int width, ++ float coef_r, float coef_g, float coef_b); ++ + //-------------------------------------- + // + // Fluid kernels: RGB-to-HSV +@@ -285,6 +294,43 @@ void run_rgb2gray_impl(uchar out[], const uchar in[], int width, + } + } + ++//---------------------------------- ++// ++// Fluid kernels: RGBA2Gray, BGRA2Gray ++// ++//---------------------------------- ++ ++void run_rgba2gray_impl(uchar out[], const uchar in[], int width, ++ float coef_r, float coef_g, float coef_b) ++{ ++ // assume: ++ // - coefficients are less than 1 ++ // - and their sum equals 1 ++ ++ constexpr int unity = 1 << 16; // Q0.0.16 inside ushort: ++ ushort rc = static_cast(coef_r * unity + 0.5f); ++ ushort gc = static_cast(coef_g * unity + 0.5f); ++ ushort bc = static_cast(coef_b * unity + 0.5f); ++ ++ GAPI_Assert(rc + gc + bc <= unity); ++ GAPI_Assert(rc + gc + bc >= USHRT_MAX); ++ ++#if CV_SIMD ++ // TODO ++#endif ++ ++ for (int w=0; w < width; w++) ++ { ++ uchar r = in[4*w ]; ++ uchar g = in[4*w + 1]; ++ uchar b = in[4*w + 2]; ++ ++ static const int half = 1 << 15; // Q0.0.16 ++ ushort y = (r*rc + b*bc + g*gc + half) >> 16; ++ out[w] = static_cast(y); ++ } ++} ++ + //-------------------------------------- + // + // Fluid kernels: RGB-to-HSV +diff --git a/modules/gapi/src/backends/ocl/goclimgproc.cpp b/modules/gapi/src/backends/ocl/goclimgproc.cpp +index 07069ae83e..ff597c820a 100644 +--- a/modules/gapi/src/backends/ocl/goclimgproc.cpp ++++ b/modules/gapi/src/backends/ocl/goclimgproc.cpp +@@ -245,6 +245,14 @@ GAPI_OCL_KERNEL(GOCLRGB2Gray, cv::gapi::imgproc::GRGB2Gray) + } + }; + ++GAPI_OCL_KERNEL(GOCLRGBA2Gray, cv::gapi::imgproc::GRGBA2Gray) ++{ ++ static void run(const cv::UMat& in, cv::UMat &out) ++ { ++ cv::cvtColor(in, out, cv::COLOR_RGBA2GRAY); ++ } ++}; ++ + GAPI_OCL_KERNEL(GOCLBGR2Gray, cv::gapi::imgproc::GBGR2Gray) + { + static void run(const cv::UMat& in, cv::UMat &out) +@@ -253,6 +261,14 @@ GAPI_OCL_KERNEL(GOCLBGR2Gray, cv::gapi::imgproc::GBGR2Gray) + } + }; + ++GAPI_OCL_KERNEL(GOCLBGRA2Gray, cv::gapi::imgproc::GBGRA2Gray) ++{ ++ static void run(const cv::UMat& in, cv::UMat &out) ++ { ++ cv::cvtColor(in, out, cv::COLOR_BGRA2GRAY); ++ } ++}; ++ + GAPI_OCL_KERNEL(GOCLRGB2GrayCustom, cv::gapi::imgproc::GRGB2GrayCustom) + { + //TODO: avoid copy +@@ -290,7 +306,9 @@ cv::gapi::GKernelPackage cv::gapi::imgproc::ocl::kernels() + , GOCLYUV2BGR + , GOCLLUV2BGR + , GOCLBGR2Gray ++ , GOCLBGRA2Gray + , GOCLRGB2Gray ++ , GOCLRGBA2Gray + , GOCLRGB2GrayCustom + >(); + return pkg; +diff --git a/modules/gapi/test/common/gapi_imgproc_tests.hpp b/modules/gapi/test/common/gapi_imgproc_tests.hpp +index 38a02985e7..8e19467476 100644 +--- a/modules/gapi/test/common/gapi_imgproc_tests.hpp ++++ b/modules/gapi/test/common/gapi_imgproc_tests.hpp +@@ -66,7 +66,9 @@ GAPI_TEST_FIXTURE_SPEC_PARAMS(GoodFeaturesTest, + blockSize, useHarrisDetector) + GAPI_TEST_FIXTURE(BGR2RGBTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF) + GAPI_TEST_FIXTURE(RGB2GrayTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF) ++GAPI_TEST_FIXTURE(RGBA2GrayTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF) + GAPI_TEST_FIXTURE(BGR2GrayTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF) ++GAPI_TEST_FIXTURE(BGRA2GrayTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF) + GAPI_TEST_FIXTURE(RGB2YUVTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF) + GAPI_TEST_FIXTURE(BGR2I420Test, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF) + GAPI_TEST_FIXTURE(RGB2I420Test, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF) +diff --git a/modules/gapi/test/common/gapi_imgproc_tests_inl.hpp b/modules/gapi/test/common/gapi_imgproc_tests_inl.hpp +index 95728e87b7..8cf69f737a 100644 +--- a/modules/gapi/test/common/gapi_imgproc_tests_inl.hpp ++++ b/modules/gapi/test/common/gapi_imgproc_tests_inl.hpp +@@ -485,6 +485,25 @@ TEST_P(RGB2GrayTest, AccuracyTest) + } + } + ++TEST_P(RGBA2GrayTest, AccuracyTest) ++{ ++ // G-API code ////////////////////////////////////////////////////////////// ++ cv::GMat in; ++ auto out = cv::gapi::RGBA2Gray(in); ++ ++ cv::GComputation c(in, out); ++ c.apply(in_mat1, out_mat_gapi, getCompileArgs()); ++ // OpenCV code ///////////////////////////////////////////////////////////// ++ { ++ cv::cvtColor(in_mat1, out_mat_ocv, cv::COLOR_RGBA2GRAY); ++ } ++ // Comparison ////////////////////////////////////////////////////////////// ++ { ++ EXPECT_TRUE(cmpF(out_mat_gapi, out_mat_ocv)); ++ EXPECT_EQ(out_mat_gapi.size(), sz); ++ } ++} ++ + TEST_P(BGR2GrayTest, AccuracyTest) + { + // G-API code ////////////////////////////////////////////////////////////// +@@ -504,6 +523,25 @@ TEST_P(BGR2GrayTest, AccuracyTest) + } + } + ++TEST_P(BGRA2GrayTest, AccuracyTest) ++{ ++ // G-API code ////////////////////////////////////////////////////////////// ++ cv::GMat in; ++ auto out = cv::gapi::BGRA2Gray(in); ++ ++ cv::GComputation c(in, out); ++ c.apply(in_mat1, out_mat_gapi, getCompileArgs()); ++ // OpenCV code ///////////////////////////////////////////////////////////// ++ { ++ cv::cvtColor(in_mat1, out_mat_ocv, cv::COLOR_BGRA2GRAY); ++ } ++ // Comparison ////////////////////////////////////////////////////////////// ++ { ++ EXPECT_TRUE(cmpF(out_mat_gapi, out_mat_ocv)); ++ EXPECT_EQ(out_mat_gapi.size(), sz); ++ } ++} ++ + TEST_P(RGB2YUVTest, AccuracyTest) + { + // G-API code ////////////////////////////////////////////////////////////// +diff --git a/modules/gapi/test/cpu/gapi_imgproc_tests_cpu.cpp b/modules/gapi/test/cpu/gapi_imgproc_tests_cpu.cpp +index e7f9667096..949097a26b 100644 +--- a/modules/gapi/test/cpu/gapi_imgproc_tests_cpu.cpp ++++ b/modules/gapi/test/cpu/gapi_imgproc_tests_cpu.cpp +@@ -257,6 +257,14 @@ INSTANTIATE_TEST_CASE_P(RGB2GrayTestCPU, RGB2GrayTest, + Values(IMGPROC_CPU), + Values(AbsExact().to_compare_obj()))); + ++INSTANTIATE_TEST_CASE_P(RGBA2GrayTestCPU, RGBA2GrayTest, ++ Combine(Values(CV_8UC4), ++ Values(cv::Size(1280, 720), ++ cv::Size(640, 480)), ++ Values(CV_8UC1), ++ Values(IMGPROC_CPU), ++ Values(AbsExact().to_compare_obj()))); ++ + INSTANTIATE_TEST_CASE_P(BGR2GrayTestCPU, BGR2GrayTest, + Combine(Values(CV_8UC3), + Values(cv::Size(1280, 720), +@@ -265,6 +273,14 @@ INSTANTIATE_TEST_CASE_P(BGR2GrayTestCPU, BGR2GrayTest, + Values(IMGPROC_CPU), + Values(AbsExact().to_compare_obj()))); + ++INSTANTIATE_TEST_CASE_P(BGRA2GrayTestCPU, BGRA2GrayTest, ++ Combine(Values(CV_8UC4), ++ Values(cv::Size(1280, 720), ++ cv::Size(640, 480)), ++ Values(CV_8UC1), ++ Values(IMGPROC_CPU), ++ Values(AbsExact().to_compare_obj()))); ++ + INSTANTIATE_TEST_CASE_P(RGB2YUVTestCPU, RGB2YUVTest, + Combine(Values(CV_8UC3), + Values(cv::Size(1280, 720), +diff --git a/modules/gapi/test/cpu/gapi_imgproc_tests_fluid.cpp b/modules/gapi/test/cpu/gapi_imgproc_tests_fluid.cpp +index 4e847825f1..cea5671508 100644 +--- a/modules/gapi/test/cpu/gapi_imgproc_tests_fluid.cpp ++++ b/modules/gapi/test/cpu/gapi_imgproc_tests_fluid.cpp +@@ -24,6 +24,14 @@ INSTANTIATE_TEST_CASE_P(RGB2GrayTestFluid, RGB2GrayTest, + Values(IMGPROC_FLUID), + Values(ToleranceColor(1e-3).to_compare_obj()))); + ++INSTANTIATE_TEST_CASE_P(RGBA2GrayTestFluid, RGBA2GrayTest, ++ Combine(Values(CV_8UC4), ++ Values(cv::Size(1280, 720), ++ cv::Size(640, 480)), ++ Values(CV_8UC1), ++ Values(IMGPROC_FLUID), ++ Values(ToleranceColor(1e-3).to_compare_obj()))); ++ + INSTANTIATE_TEST_CASE_P(BGR2GrayTestFluid, BGR2GrayTest, + Combine(Values(CV_8UC3), + Values(cv::Size(1280, 720), +@@ -32,6 +40,14 @@ INSTANTIATE_TEST_CASE_P(BGR2GrayTestFluid, BGR2GrayTest, + Values(IMGPROC_FLUID), + Values(ToleranceColor(1e-3).to_compare_obj()))); + ++INSTANTIATE_TEST_CASE_P(BGRA2GrayTestFluid, BGRA2GrayTest, ++ Combine(Values(CV_8UC4), ++ Values(cv::Size(1280, 720), ++ cv::Size(640, 480)), ++ Values(CV_8UC1), ++ Values(IMGPROC_FLUID), ++ Values(ToleranceColor(1e-3).to_compare_obj()))); ++ + INSTANTIATE_TEST_CASE_P(RGB2YUVTestFluid, RGB2YUVTest, + Combine(Values(CV_8UC3), + Values(cv::Size(1280, 720), +diff --git a/modules/gapi/test/gpu/gapi_imgproc_tests_gpu.cpp b/modules/gapi/test/gpu/gapi_imgproc_tests_gpu.cpp +index 7d9bd761a1..5377335e2e 100644 +--- a/modules/gapi/test/gpu/gapi_imgproc_tests_gpu.cpp ++++ b/modules/gapi/test/gpu/gapi_imgproc_tests_gpu.cpp +@@ -203,6 +203,14 @@ INSTANTIATE_TEST_CASE_P(RGB2GrayTestGPU, RGB2GrayTest, + Values(IMGPROC_GPU), + Values(ToleranceColor(1e-3).to_compare_obj()))); + ++INSTANTIATE_TEST_CASE_P(RGBA2GrayTestGPU, RGBA2GrayTest, ++ Combine(Values(CV_8UC4), ++ Values(cv::Size(1280, 720), ++ cv::Size(640, 480)), ++ Values(CV_8UC1), ++ Values(IMGPROC_GPU), ++ Values(ToleranceColor(1e-3).to_compare_obj()))); ++ + INSTANTIATE_TEST_CASE_P(BGR2GrayTestGPU, BGR2GrayTest, + Combine(Values(CV_8UC3), + Values(cv::Size(1280, 720), +@@ -211,6 +219,14 @@ INSTANTIATE_TEST_CASE_P(BGR2GrayTestGPU, BGR2GrayTest, + Values(IMGPROC_GPU), + Values(ToleranceColor(1e-3).to_compare_obj()))); + ++INSTANTIATE_TEST_CASE_P(BGRA2GrayTestGPU, BGRA2GrayTest, ++ Combine(Values(CV_8UC4), ++ Values(cv::Size(1280, 720), ++ cv::Size(640, 480)), ++ Values(CV_8UC1), ++ Values(IMGPROC_GPU), ++ Values(ToleranceColor(1e-3).to_compare_obj()))); ++ + INSTANTIATE_TEST_CASE_P(RGB2YUVTestGPU, RGB2YUVTest, + Combine(Values(CV_8UC3), + Values(cv::Size(1280, 720), +-- +2.17.1 + diff --git a/tools/depends/opencv/0001-temp-Hack-opencv.js-to-ES6.patch b/tools/depends/opencv/0001-temp-Hack-opencv.js-to-ES6.patch new file mode 100644 index 000000000..496863da9 --- /dev/null +++ b/tools/depends/opencv/0001-temp-Hack-opencv.js-to-ES6.patch @@ -0,0 +1,63 @@ +From 4b9c950da3527fc30eb98ac68cabcdc5d169d27b Mon Sep 17 00:00:00 2001 +Date: Mon, 29 Jun 2020 23:13:29 -0700 +Subject: [PATCH] [temp] Hack opencv.js to ES6 + +--- + opencv.js | 39 +++------------------------------------ + 1 file changed, 3 insertions(+), 36 deletions(-) + +diff --git a/opencv.js b/opencv.js +index ee6cbb2..03e1ef9 100644 +--- a/opencv.js ++++ b/opencv.js +@@ -1,26 +1,3 @@ +-(function (root, factory) { +- if (typeof define === 'function' && define.amd) { +- // AMD. Register as an anonymous module. +- define(function () { +- return (root.cv = factory()); +- }); +- } else if (typeof module === 'object' && module.exports) { +- // Node. Does not work with strict CommonJS, but +- // only CommonJS-like environments that support module.exports, +- // like Node. +- module.exports = factory(); +- } else if (typeof window === 'object') { +- // Browser globals +- root.cv = factory(); +- } else if (typeof importScripts === 'function') { +- // Web worker +- root.cv = factory; +- } else { +- // Other shells, e.g. d8 +- root.cv = factory(); +- } +-}(this, function () { +- + var cv = (function() { + var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined; + return ( +@@ -33,16 +10,6 @@ var Module=typeof cv!=="undefined"?cv:{};var moduleOverrides={};var key;for(key + return cv + } + ); +-})(); +-if (typeof exports === 'object' && typeof module === 'object') +- module.exports = cv; +- else if (typeof define === 'function' && define['amd']) +- define([], function() { return cv; }); +- else if (typeof exports === 'object') +- exports["cv"] = cv; +- +- if (typeof Module === 'undefined') +- Module = {}; +- return cv(Module); +-})); +- +\ No newline at end of file ++})()(); ++ ++export { cv as default }; +-- +2.20.1 + diff --git a/tools/depends/opencv/opencv_js.config.py b/tools/depends/opencv/opencv_js.config.py new file mode 100644 index 000000000..2259464d0 --- /dev/null +++ b/tools/depends/opencv/opencv_js.config.py @@ -0,0 +1,444 @@ +################################################################################ +# +# Copyright (C) 2020-2023 retro.ai +# This file is part of retro-dapp - https://github.com/RetroAI/retro-dapp +# +# SPDX-License-Identifier: Apache-2.0 +# See the file LICENSE.txt for more information. +# +################################################################################ + +# Classes and methods whitelist +core = { + "": [ + "absdiff", + "add", + "addWeighted", + "bitwise_and", + "bitwise_not", + "bitwise_or", + "bitwise_xor", + "cartToPolar", + "compare", + "convertScaleAbs", + "copyMakeBorder", + "countNonZero", + "determinant", + "dft", + "divide", + "eigen", + "exp", + "flip", + "getOptimalDFTSize", + "gemm", + "hconcat", + "inRange", + "invert", + "kmeans", + "log", + "magnitude", + "max", + "mean", + "meanStdDev", + "merge", + "min", + "minMaxLoc", + "mixChannels", + "multiply", + "norm", + "normalize", + "perspectiveTransform", + "polarToCart", + "pow", + "randn", + "randu", + "reduce", + "repeat", + "rotate", + "setIdentity", + "setRNGSeed", + "solve", + "solvePoly", + "split", + "sqrt", + "subtract", + "trace", + "transform", + "transpose", + "vconcat", + ], + "Algorithm": [], +} + +imgproc = { + "": [ + "Canny", + "GaussianBlur", + "Laplacian", + "HoughLines", + "HoughLinesP", + "HoughCircles", + "Scharr", + "Sobel", + "adaptiveThreshold", + "approxPolyDP", + "arcLength", + "bilateralFilter", + "blur", + "boundingRect", + "boxFilter", + "calcBackProject", + "calcHist", + "circle", + "compareHist", + "connectedComponents", + "connectedComponentsWithStats", + "contourArea", + "convexHull", + "convexityDefects", + "cornerHarris", + "cornerMinEigenVal", + "createCLAHE", + "createLineSegmentDetector", + "cvtColor", + "demosaicing", + "dilate", + "distanceTransform", + "distanceTransformWithLabels", + "drawContours", + "ellipse", + "ellipse2Poly", + "equalizeHist", + "erode", + "filter2D", + "findContours", + "fitEllipse", + "fitLine", + "floodFill", + "getAffineTransform", + "getPerspectiveTransform", + "getRotationMatrix2D", + "getStructuringElement", + "goodFeaturesToTrack", + "grabCut", + "initUndistortRectifyMap", + "integral", + "integral2", + "isContourConvex", + "line", + "matchShapes", + "matchTemplate", + "medianBlur", + "minAreaRect", + "minEnclosingCircle", + "moments", + "morphologyEx", + "pointPolygonTest", + "putText", + "pyrDown", + "pyrUp", + "rectangle", + "remap", + "resize", + "sepFilter2D", + "threshold", + "undistort", + "warpAffine", + "warpPerspective", + "warpPolar", + "watershed", + "fillPoly", + "fillConvexPoly", + ], + "CLAHE": [ + "apply", + "collectGarbage", + "getClipLimit", + "getTilesGridSize", + "setClipLimit", + "setTilesGridSize", + ], +} + +objdetect = { + "": ["groupRectangles"], + "HOGDescriptor": [ + "load", + "HOGDescriptor", + "getDefaultPeopleDetector", + "getDaimlerPeopleDetector", + "setSVMDetector", + "detectMultiScale", + ], + "CascadeClassifier": [ + "load", + "detectMultiScale2", + "CascadeClassifier", + "detectMultiScale3", + "empty", + "detectMultiScale", + ], +} + +video = { + "": [ + "CamShift", + "buildOpticalFlowPyramid", + "calcOpticalFlowFarneback", + "calcOpticalFlowPyrLK", + "createBackgroundSubtractorMOG2", + "findTransformECC", + "meanShift", + ], + "BackgroundSubtractorMOG2": ["BackgroundSubtractorMOG2", "apply"], + "BackgroundSubtractor": ["apply", "getBackgroundImage"], +} + +dnn = { + "dnn_Net": ["setInput", "forward"], + "": [ + "readNetFromCaffe", + "readNetFromTensorflow", + "readNetFromTorch", + "readNetFromDarknet", + "readNetFromONNX", + "readNet", + "blobFromImage", + ], +} + +features2d = { + "Feature2D": [ + "detect", + "compute", + "detectAndCompute", + "descriptorSize", + "descriptorType", + "defaultNorm", + "empty", + "getDefaultName", + ], + "BRISK": ["create", "getDefaultName"], + "ORB": [ + "create", + "setMaxFeatures", + "setScaleFactor", + "setNLevels", + "setEdgeThreshold", + "setFirstLevel", + "setWTA_K", + "setScoreType", + "setPatchSize", + "getFastThreshold", + "getDefaultName", + ], + "MSER": [ + "create", + "detectRegions", + "setDelta", + "getDelta", + "setMinArea", + "getMinArea", + "setMaxArea", + "getMaxArea", + "setPass2Only", + "getPass2Only", + "getDefaultName", + ], + "FastFeatureDetector": [ + "create", + "setThreshold", + "getThreshold", + "setNonmaxSuppression", + "getNonmaxSuppression", + "setType", + "getType", + "getDefaultName", + ], + "AgastFeatureDetector": [ + "create", + "setThreshold", + "getThreshold", + "setNonmaxSuppression", + "getNonmaxSuppression", + "setType", + "getType", + "getDefaultName", + ], + "GFTTDetector": [ + "create", + "setMaxFeatures", + "getMaxFeatures", + "setQualityLevel", + "getQualityLevel", + "setMinDistance", + "getMinDistance", + "setBlockSize", + "getBlockSize", + "setHarrisDetector", + "getHarrisDetector", + "setK", + "getK", + "getDefaultName", + ], + # 'SimpleBlobDetector': ['create'], + "KAZE": [ + "create", + "setExtended", + "getExtended", + "setUpright", + "getUpright", + "setThreshold", + "getThreshold", + "setNOctaves", + "getNOctaves", + "setNOctaveLayers", + "getNOctaveLayers", + "setDiffusivity", + "getDiffusivity", + "getDefaultName", + ], + "AKAZE": [ + "create", + "setDescriptorType", + "getDescriptorType", + "setDescriptorSize", + "getDescriptorSize", + "setDescriptorChannels", + "getDescriptorChannels", + "setThreshold", + "getThreshold", + "setNOctaves", + "getNOctaves", + "setNOctaveLayers", + "getNOctaveLayers", + "setDiffusivity", + "getDiffusivity", + "getDefaultName", + ], + "DescriptorMatcher": [ + "add", + "clear", + "empty", + "isMaskSupported", + "train", + "match", + "knnMatch", + "radiusMatch", + "clone", + "create", + ], + "BFMatcher": ["isMaskSupported", "create"], + "": ["drawKeypoints", "drawMatches", "drawMatchesKnn"], +} + +photo = { + "": [ + "createAlignMTB", + "createCalibrateDebevec", + "createCalibrateRobertson", + "createMergeDebevec", + "createMergeMertens", + "createMergeRobertson", + "createTonemapDrago", + "createTonemapMantiuk", + "createTonemapReinhard", + "inpaint", + ], + "CalibrateCRF": ["process"], + "AlignMTB": [ + "calculateShift", + "shiftMat", + "computeBitmaps", + "getMaxBits", + "setMaxBits", + "getExcludeRange", + "setExcludeRange", + "getCut", + "setCut", + ], + "CalibrateDebevec": [ + "getLambda", + "setLambda", + "getSamples", + "setSamples", + "getRandom", + "setRandom", + ], + "CalibrateRobertson": [ + "getMaxIter", + "setMaxIter", + "getThreshold", + "setThreshold", + "getRadiance", + ], + "MergeExposures": ["process"], + "MergeDebevec": ["process"], + "MergeMertens": [ + "process", + "getContrastWeight", + "setContrastWeight", + "getSaturationWeight", + "setSaturationWeight", + "getExposureWeight", + "setExposureWeight", + ], + "MergeRobertson": ["process"], + "Tonemap": ["process", "getGamma", "setGamma"], + "TonemapDrago": [ + "getSaturation", + "setSaturation", + "getBias", + "setBias", + "getSigmaColor", + "setSigmaColor", + "getSigmaSpace", + "setSigmaSpace", + ], + "TonemapMantiuk": ["getScale", "setScale", "getSaturation", "setSaturation"], + "TonemapReinhard": [ + "getIntensity", + "setIntensity", + "getLightAdaptation", + "setLightAdaptation", + "getColorAdaptation", + "setColorAdaptation", + ], +} + +aruco = { + "": [ + "detectMarkers", + "drawDetectedMarkers", + "drawAxis", + "estimatePoseSingleMarkers", + "estimatePoseBoard", + "estimatePoseCharucoBoard", + "interpolateCornersCharuco", + "drawDetectedCornersCharuco", + ], + "aruco_Dictionary": ["get", "drawMarker"], + "aruco_Board": ["create"], + "aruco_GridBoard": ["create", "draw"], + "aruco_CharucoBoard": ["create", "draw"], +} + +calib3d = { + "": [ + "findHomography", + "calibrateCameraExtended", + "drawFrameAxes", + "estimateAffine2D", + "getDefaultNewCameraMatrix", + "initUndistortRectifyMap", + "Rodrigues", + "findEssentialMat", + "recoverPose", + "recoverPoseDNE", + ] +} + + +white_list = makeWhiteList( + [core, imgproc, objdetect, video, dnn, features2d, photo, aruco, calib3d] +) diff --git a/tools/depends/opencv/package.mk b/tools/depends/opencv/package.mk new file mode 100644 index 000000000..281a57a26 --- /dev/null +++ b/tools/depends/opencv/package.mk @@ -0,0 +1,251 @@ +################################################################################ +# +# Copyright (C) 2020-2023 retro.ai +# This file is part of retro-dapp - https://github.com/RetroAI/retro-dapp +# +# SPDX-License-Identifier: Apache-2.0 +# See the file LICENSE.txt for more information. +# +################################################################################ + +################################################################################ +# +# OpenCV - The Open Computer Vision Library +# +# Required parameters: +# +# * USE_CONTRIB - Set to 1 to build with OpenCV's extra modules from the +# contributory repo (TODO) +# +# SPDX-License-Identifier: Apache-2.0 +# +################################################################################ + +# Dependency name and version +OPENCV_REPO_NAME = opencv +OPENCV_VERSION = 4.5.0 +OPENCV_REMOTE_REPO = https://github.com/opencv/$(OPENCV_REPO_NAME).git +OPENCV_LIB = libopencv_core.a +OPENCV_JS_LIB = opencv.js + +# OpenCV extra modules +OPENCV_CONTRIB_REPO_NAME = opencv_contrib +OPENCV_CONTRIB_REMOTE_REPO = https://github.com/opencv/$(OPENCV_CONTRIB_REPO_NAME).git + +################################################################################ +# +# Paths +# +################################################################################ + +# Checkout directory +REPO_DIR_OPENCV = $(REPO_DIR)/$(OPENCV_REPO_NAME) +REPO_DIR_OPENCV_CONTRIB = $(REPO_DIR)/$(OPENCV_CONTRIB_REPO_NAME) + +# Build directory +BUILD_DIR_OPENCV = $(BUILD_DIR)/$(OPENCV_REPO_NAME) + +# Build output +BUILD_FILE_OPENCV = $(BUILD_DIR_OPENCV)/lib/$(OPENCV_LIB) +BUILD_FILE_OPENCV_JS = $(BUILD_DIR_OPENCV)/bin/$(OPENCV_JS_LIB) + +# Install output +INSTALL_FILE_OPENCV = $(DEPENDS_DIR)/lib/$(OPENCV_LIB) +INSTALL_FILE_OPENCV_JS = $(INSTALL_DIR)/$(OPENCV_JS_LIB) + +################################################################################ +# +# Configuration +# +################################################################################ + +OPENCV_GAPI_BUILD_DEPENDS = \ + $(S)/install-ade \ + +OPENCV_SFM_BUILD_DEPENDS = \ + $(S)/install-ceres \ + +OPENCV_BUILD_DEPENDS = \ + $(S)/checkout-opencv \ + $(S)/build-emsdk \ + $(OPENCV_GAPI_BUILD_DEPENDS) \ + $(OPENCV_SFM_BUILD_DEPENDS) \ + +ifeq ($(PLATFORM),darwin) + #OPENCV_BUILD_DEPENDS += $(S)/checkout-android-sdk +endif + +################################################################################ +# +# Checkout +# +################################################################################ + +$(S)/checkout-opencv: $(S)/.precheckout \ + $(TOOL_DIR)/depends/opencv/0001-Fix-sfm-disabled-when-Eigen-is-present.patch + [ -d "$(REPO_DIR_OPENCV)" ] || ( \ + git clone -b $(OPENCV_VERSION) "$(OPENCV_REMOTE_REPO)" "$(REPO_DIR_OPENCV)" && \ + patch -p1 --forward --directory="$(REPO_DIR_OPENCV)" < \ + "$(TOOL_DIR)/depends/opencv/0001-GAPI-Implement-RGBA2Gray-and-GBRA2Gray.patch" \ + ) + + [ -d "$(REPO_DIR_OPENCV_CONTRIB)" ] || ( \ + git clone -b $(OPENCV_VERSION) "$(OPENCV_CONTRIB_REMOTE_REPO)" "$(REPO_DIR_OPENCV_CONTRIB)" \ + ) + + @# TODO: Repository sync is delegated to the CI system. + + patch -p1 --forward --directory="$(REPO_DIR_OPENCV_CONTRIB)" < \ + "$(TOOL_DIR)/depends/opencv/0001-Fix-sfm-disabled-when-Eigen-is-present.patch" || ( \ + code=$$?; [[ "$${code}" -lt "2" ]] || exit $${code}; \ + ) + + touch "$@" + +################################################################################ +# +# Patch +# +################################################################################ + +$(S)/patch-opencv: $(S)/.prepatch $(S)/checkout-opencv \ + $(TOOL_DIR)/depends/opencv/opencv_js.config.py + cp "$(TOOL_DIR)/depends/opencv/opencv_js.config.py" "$(REPO_DIR_OPENCV)/platforms/js" + + touch "$@" + +################################################################################ +# +# Build +# +################################################################################ + +CMAKE_CONTRIB_PARAMETERS = \ + -DOPENCV_EXTRA_MODULES_PATH="$(REPO_DIR_OPENCV_CONTRIB)/modules" \ + +CMAKE_CONTRIB_MODULES = \ + -DBUILD_opencv_aruco=OFF \ + -DBUILD_opencv_sfm=ON \ + +$(BUILD_FILE_OPENCV): $(S)/.prebuild $(OPENCV_BUILD_DEPENDS) + mkdir -p "$(BUILD_DIR_OPENCV)" + + # Activate PATH and other environment variables in the current terminal and + # build OpenCV + . "$(REPO_DIR_EMSDK)/emsdk_set_env.sh" && \ + cd "${BUILD_DIR_OPENCV}" && \ + emcmake cmake "$(REPO_DIR_OPENCV)" \ + -DCMAKE_FIND_ROOT_PATH="$(DEPENDS_DIR)" \ + -DCMAKE_INSTALL_PREFIX="$(DEPENDS_DIR)" \ + $(CMAKE_CONTRIB_PARAMETERS) \ + $(CMAKE_CONTRIB_MODULES) \ + -DCMAKE_BUILD_PARALLEL_LEVEL=$(shell getconf _NPROCESSORS_ONLN) \ + $(shell ! command -v ccache &> /dev/null || echo "-DCMAKE_CXX_COMPILER_LAUNCHER=ccache") \ + -DBUILD_SHARED_LIBS=OFF \ + -DWITH_1394=OFF \ + -DWITH_ADE=ON \ + -DWITH_VTK=OFF \ + -DWITH_EIGEN=OFF \ + -DWITH_FFMPEG=OFF \ + -DWITH_GSTREAMER=OFF \ + -DWITH_GTK=OFF \ + -DWITH_GTK_2_X=OFF \ + -DWITH_IPP=OFF \ + -DWITH_JASPER=OFF \ + -DWITH_JPEG=OFF \ + -DWITH_WEBP=OFF \ + -DWITH_OPENEXR=OFF \ + -DWITH_OPENGL=OFF \ + -DWITH_OPENVX=OFF \ + -DWITH_OPENNI=OFF \ + -DWITH_OPENNI2=OFF \ + -DWITH_PNG=OFF \ + -DWITH_TBB=OFF \ + -DWITH_TIFF=OFF \ + -DWITH_V4L=OFF \ + -DWITH_OPENCL=OFF \ + -DWITH_OPENCL_SVM=OFF \ + -DWITH_OPENCLAMDFFT=OFF \ + -DWITH_OPENCLAMDBLAS=OFF \ + -DWITH_GPHOTO2=OFF \ + -DWITH_LAPACK=OFF \ + -DWITH_ITT=OFF \ + -DWITH_QUIRC=OFF \ + -DBUILD_ZLIB=ON \ + -DBUILD_opencv_apps=OFF \ + -DBUILD_opencv_calib3d=ON \ + -DBUILD_opencv_dnn=ON \ + -DBUILD_opencv_features2d=ON \ + -DBUILD_opencv_flann=ON \ + -DBUILD_opencv_gapi=ON \ + -DBUILD_opencv_ml=OFF \ + -DBUILD_opencv_photo=ON \ + -DBUILD_opencv_imgcodecs=ON \ + -DBUILD_opencv_shape=OFF \ + -DBUILD_opencv_videoio=OFF \ + -DBUILD_opencv_videostab=OFF \ + -DBUILD_opencv_highgui=OFF \ + -DBUILD_opencv_superres=OFF \ + -DBUILD_opencv_stitching=OFF \ + -DBUILD_opencv_java=OFF \ + -DBUILD_opencv_java_bindings_generator=OFF \ + -DBUILD_opencv_js=ON \ + -DBUILD_opencv_js_bindings_generator=ON \ + -DBUILD_opencv_python2=OFF \ + -DBUILD_opencv_python3=OFF \ + -DBUILD_opencv_python_bindings_generator=OFF \ + -DBUILD_EXAMPLES=OFF \ + -DBUILD_PACKAGE=OFF \ + -DBUILD_TESTS=OFF \ + -DBUILD_PERF_TESTS=OFF \ + -DBUILD_DOCS=OFF \ + -DWITH_PTHREADS_PF=OFF \ + -DCV_ENABLE_INTRINSICS=OFF \ + -DBUILD_WASM_INTRIN_TESTS=OFF \ + -DCMAKE_C_FLAGS=" \ + -s WASM=1 \ + -s USE_PTHREADS=0 \ + -s DISABLE_EXCEPTION_CATCHING=1 \ + " \ + -DCMAKE_CXX_FLAGS=" \ + -s WASM=1 \ + -s USE_PTHREADS=0 \ + -s DISABLE_EXCEPTION_CATCHING=1 \ + " \ + + OPENCV_JS_WHITELIST="$(TOOL_DIR)/depends/opencv/opencv_js.config.py" \ + make -C "${BUILD_DIR_OPENCV}" -j$(shell getconf _NPROCESSORS_ONLN) + + touch "$@" + +$(S)/build-opencv: $(BUILD_FILE_OPENCV) + touch "$@" + +################################################################################ +# +# Install +# +################################################################################ + +$(INSTALL_FILE_OPENCV): $(S)/.preinstall $(S)/build-opencv + mkdir -p "$(DEPENDS_DIR)" + + # Install headers and libraries + cmake \ + --build "$(BUILD_DIR_OPENCV)" \ + --target install + + touch "$@" + +$(INSTALL_FILE_OPENCV_JS): $(S)/.preinstall $(S)/build-opencv \ + $(TOOL_DIR)/depends/opencv/0001-temp-Hack-opencv.js-to-ES6.patch + mkdir -p "$(INSTALL_DIR)" + + # Copy generated files + cp "$(BUILD_FILE_OPENCV_JS)" "$(INSTALL_DIR)" + + # Hack in ES6 support + patch --no-backup-if-mismatch -d "$(INSTALL_DIR)" < "$(TOOL_DIR)/depends/opencv/0001-temp-Hack-opencv.js-to-ES6.patch" + +$(S)/install-opencv: $(INSTALL_FILE_OPENCV) $(INSTALL_FILE_OPENCV_JS) + touch "$@" diff --git a/tools/depends/threads/0001-Fix-browser-error-bundling-with-Snowpack.patch b/tools/depends/threads/0001-Fix-browser-error-bundling-with-Snowpack.patch new file mode 100644 index 000000000..b2aa5e422 --- /dev/null +++ b/tools/depends/threads/0001-Fix-browser-error-bundling-with-Snowpack.patch @@ -0,0 +1,49 @@ +From 7885b23fa11c8305b96fcd886c88e8f3609c9e2f Mon Sep 17 00:00:00 2001 +Date: Sun, 12 Jul 2020 16:06:14 -0700 +Subject: [PATCH] Fix browser error bundling with Snowpack + +For some reason, building with Snowpack, Babel and Rollup transforms the +final if-block in the file to be: + + if (undefined.on === "function") ; + export { BlobWorker, DefaultSerializer, Pool, Thread, Transfer, ... }; + +Troubleshooting was unable to locate the erroneous transformation. + +Error was: + + Uncaught TypeError: Cannot read property 'on' of undefined +--- + dist-esm/worker/index.js | 2 +- + dist/worker/index.js | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/dist-esm/worker/index.js b/dist-esm/worker/index.js +index fd5db13..72f75ff 100644 +--- a/dist-esm/worker/index.js ++++ b/dist-esm/worker/index.js +@@ -185,7 +185,7 @@ if (typeof self !== "undefined" && typeof self.addEventListener === "function" & + } + }); + } +-if (typeof process !== "undefined" && typeof process.on === "function" && Implementation.isWorkerRuntime()) { ++if (typeof process !== "undefined" && Implementation.isWorkerRuntime()) { + process.on("uncaughtException", (error) => { + // Post with some delay, so the master had some time to subscribe to messages + setTimeout(() => postUncaughtErrorMessage(error), 250); +diff --git a/dist/worker/index.js b/dist/worker/index.js +index 291e84c..6b1c337 100644 +--- a/dist/worker/index.js ++++ b/dist/worker/index.js +@@ -194,7 +194,7 @@ if (typeof self !== "undefined" && typeof self.addEventListener === "function" & + } + }); + } +-if (typeof process !== "undefined" && typeof process.on === "function" && implementation_1.default.isWorkerRuntime()) { ++if (typeof process !== "undefined" && implementation_1.default.isWorkerRuntime()) { + process.on("uncaughtException", (error) => { + // Post with some delay, so the master had some time to subscribe to messages + setTimeout(() => postUncaughtErrorMessage(error), 250); +-- +2.20.1 + diff --git a/tools/npm-depends.sh b/tools/npm-depends.sh new file mode 100755 index 000000000..0e76e9659 --- /dev/null +++ b/tools/npm-depends.sh @@ -0,0 +1,93 @@ +#!/bin/bash +################################################################################ +# +# Copyright (C) 2020-2023 retro.ai +# This file is part of retro-dapp - https://github.com/RetroAI/retro-dapp +# +# SPDX-License-Identifier: Apache-2.0 +# See the file LICENSE.txt for more information. +# +################################################################################ + +# +# NPM scripting entry point +# +# Call via: +# +# npm-depends.sh +# +# See the function dispatch() for the available tasks that can be run. +# + +# Enable strict mode +set -o errexit +set -o pipefail +set -o nounset + +# Absolute path to this script +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# +# Source includes +# + +source "${SCRIPT_DIR}/npm-paths.sh" + +# +# Dispatch function +# +# This function contains the available tasks. The first argument identifies +# which task to jump to. +# +function dispatch() { + case $1 in + all) + depends-all + ;; + checkout) + depends-checkout + ;; + build) + depends-build + ;; + install) + depends-install + ;; + *) + echo "Invalid task: $1" + exit 1 + ;; + esac +} + +function depends-all() { + # Dependencies to build + BUILD_DEPENDS="emscripten " + + # Build OpenCV + if [ ! -f "${GENERATED_SOURCE_DIR}/opencv.js" ] \ + || [ ! -f "${DISTRIBUTION_LIB_DIR}/libopencv_core.a" ]; then + rm -f "${STAMP_DIR}/build-opencv" + BUILD_DEPENDS+="opencv " + fi + + make -C "${TOOL_DIR}" -j$(getconf _NPROCESSORS_ONLN) ${BUILD_DEPENDS} + + # Build C++ libraries + "${CPP_LIBRARY_DIR}/build-ci.sh" +} + +function depends-checkout() { + make -C "${TOOL_DIR}" checkout -j10 +} + +function depends-build() { + make -C "${TOOL_DIR}" build -j$(getconf _NPROCESSORS_ONLN) +} + +function depends-install() { + make -C "${TOOL_DIR}" install +} + +# Perform the dispatch +dispatch $1 diff --git a/tools/npm-paths.sh b/tools/npm-paths.sh new file mode 100755 index 000000000..b6faa153b --- /dev/null +++ b/tools/npm-paths.sh @@ -0,0 +1,51 @@ +#!/bin/bash +################################################################################ +# +# Copyright (C) 2020-2023 retro.ai +# This file is part of retro-dapp - https://github.com/RetroAI/retro-dapp +# +# SPDX-License-Identifier: Apache-2.0 +# See the file LICENSE.txt for more information. +# +################################################################################ + +# +# Paths for NPM scripts +# +# Import via: +# +# source npm-paths.sh +# + +# Enable strict mode +set -o errexit +set -o pipefail +set -o nounset + +# +# Directory definitions +# + +# Typescript/Javascript source directory +SOURCE_DIR="src" + +# Directory for generated source +GENERATED_SOURCE_DIR="${SOURCE_DIR}/generated" + +# C++ libraries directory +CPP_LIBRARY_DIR="lib" + +# Tooling directory +TOOL_DIR="tools" + +# Depends directory +DEPENDS_DIR="${TOOL_DIR}/depends" + +# Build system stamp directory +STAMP_DIR="${TOOL_DIR}/stamps" + +# Location of installed dependency files +DISTRIBUTION_DIR="${TOOL_DIR}/dist" + +# Location of installed dependency libraries +DISTRIBUTION_LIB_DIR="${DISTRIBUTION_DIR}/lib" diff --git a/tools/setup_environment.mk b/tools/setup_environment.mk new file mode 100644 index 000000000..a7ad92139 --- /dev/null +++ b/tools/setup_environment.mk @@ -0,0 +1,36 @@ +################################################################################ +# +# Copyright (C) 2020-2023 retro.ai +# This file is part of retro-dapp - https://github.com/RetroAI/retro-dapp +# +# SPDX-License-Identifier: Apache-2.0 +# See the file LICENSE.txt for more information. +# +################################################################################ + +################################################################################ +# +# Set properties based on the environment +# +################################################################################ + +# +# Operating system detection +# + +PLATFORM = +ifeq ($(OS),Windows_NT) + PLATFORM = windows +else + KERNEL_NAME = $(shell uname -s) + ifeq ($(KERNEL_NAME),Linux) + PLATFORM = linux + else ifeq ($(KERNEL_NAME),Darwin) + PLATFORM = darwin + else + PROCESSOR = $(shell uname -p) + ifneq ($(filter arm%,$(PROCESSOR)),) + PLATFORM = arm + endif + endif +endif diff --git a/tools/setup_paths.mk b/tools/setup_paths.mk new file mode 100644 index 000000000..b68f634bd --- /dev/null +++ b/tools/setup_paths.mk @@ -0,0 +1,41 @@ +################################################################################ +# +# Copyright (C) 2020-2023 retro.ai +# This file is part of retro-dapp - https://github.com/RetroAI/retro-dapp +# +# SPDX-License-Identifier: Apache-2.0 +# See the file LICENSE.txt for more information. +# +################################################################################ + +################################################################################ +# +# Set paths for build system early setup +# +################################################################################ + +# Directory for tooling +TOOL_DIR = $(shell pwd) + +# Directory of stamps for tracking build progress +STAMP_DIR = $(TOOL_DIR)/stamps + +# Shorten variable name for Makefile stamp idiom +S = $(STAMP_DIR) + +# Directory for storing dependency repositories +REPO_DIR = $(TOOL_DIR)/repos + +# Directory of building dependencies +BUILD_DIR = $(TOOL_DIR)/build + +# Directory to place generated files +INSTALL_DIR = $(TOOL_DIR)/../src/generated + +# Directory to place C++ library dependencies +DEPENDS_DIR = $(TOOL_DIR)/dist + +# Stamp files for build system stages +CHECKOUT_DONE = $(STAMP_DIR)/.checkout-done +BUILD_DONE = $(STAMP_DIR)/.build-done +INSTALL_DONE = $(STAMP_DIR)/.install-done diff --git a/tools/setup_stages.mk b/tools/setup_stages.mk new file mode 100644 index 000000000..3dc20b644 --- /dev/null +++ b/tools/setup_stages.mk @@ -0,0 +1,81 @@ +################################################################################ +# +# Copyright (C) 2020-2023 retro.ai +# This file is part of retro-dapp - https://github.com/RetroAI/retro-dapp +# +# SPDX-License-Identifier: Apache-2.0 +# See the file LICENSE.txt for more information. +# +################################################################################ + +################################################################################ +# +# Build system stages +# +# Depends on the following variables: +# +# - CHECKOUT_DEPENDS: The checkout stage targets +# - BUILD_DEPENDS: The build stage targets +# - INSTALL_DEPENDS: The install stage targets +# +################################################################################ + +include setup_paths.mk + +# Phony targets for build stages +.PHONY: checkout +.PHONY: build +.PHONY: install +.PHONY: all +.PHONE: clean +.PHONY: distclean + +# Set the stage used when make is called with no arguments +all: install + +################################################################################ +# +# Build stage setup +# +# Dependency procedures must depend on these. +# +################################################################################ + +# +# Setup checkout stage +# + +$(S)/.precheckout: + mkdir -p "$(S)" + mkdir -p "$(REPO_DIR)" + + touch "$@" + +# +# Setup patch stage +# + +$(S)/.prepatch: + mkdir -p "$(S)" + + touch "$@" + +# +# Setup build stage +# + +$(S)/.prebuild: + mkdir -p "$(S)" + mkdir -p "$(BUILD_DIR)" + + touch "$@" + +# +# Setup install stage +# + +$(S)/.preinstall: + mkdir -p "$(S)" + mkdir -p "$(INSTALL_DIR)" + + touch "$@"