redisgned v4d-contexts to take variadic arguments instead of lamda-capturing.

pull/3471/head
kallaballa 2 years ago
parent 2d3e74da84
commit a9dfdbf8bc
  1. 42
      modules/v4d/include/opencv2/v4d/detail/framebuffercontext.hpp
  2. 4
      modules/v4d/include/opencv2/v4d/detail/glcontext.hpp
  3. 4
      modules/v4d/include/opencv2/v4d/detail/nanovgcontext.hpp
  4. 5
      modules/v4d/include/opencv2/v4d/detail/timetracker.hpp
  5. 10
      modules/v4d/include/opencv2/v4d/util.hpp
  6. 77
      modules/v4d/include/opencv2/v4d/v4d.hpp
  7. 24
      modules/v4d/samples/beauty-demo.cpp
  8. 2
      modules/v4d/samples/cube-demo.cpp
  9. 6
      modules/v4d/samples/custom_source_and_sink.cpp
  10. 8
      modules/v4d/samples/display_image_fb.cpp
  11. 20
      modules/v4d/samples/display_image_nvg.cpp
  12. 24
      modules/v4d/samples/font-demo.cpp
  13. 6
      modules/v4d/samples/font_rendering.cpp
  14. 10
      modules/v4d/samples/font_with_gui.cpp
  15. 10
      modules/v4d/samples/many_cubes-demo.cpp
  16. 6
      modules/v4d/samples/nanovg-demo.cpp
  17. 2
      modules/v4d/samples/optflow-demo.cpp
  18. 8
      modules/v4d/samples/pedestrian-demo.cpp
  19. 4
      modules/v4d/samples/shader-demo.cpp
  20. 2
      modules/v4d/samples/vector_graphics.cpp
  21. 2
      modules/v4d/samples/vector_graphics_and_fb.cpp
  22. 6
      modules/v4d/samples/video_editing.cpp
  23. 20
      modules/v4d/src/detail/framebuffercontext.cpp
  24. 8
      modules/v4d/src/detail/glcontext.cpp
  25. 6
      modules/v4d/src/detail/nanovgcontext.cpp
  26. 2
      modules/v4d/src/detail/timetracker.cpp
  27. 85
      modules/v4d/src/v4d.cpp

@ -12,10 +12,12 @@
//FIXME
#include "opencv2/v4d/detail/cl.hpp"
#include <opencv2/core.hpp>
#include <opencv2/core/ocl.hpp>
#include "opencv2/v4d/util.hpp"
#include <iostream>
#include <map>
#include <vector>
struct GLFWwindow;
typedef unsigned int GLenum;
@ -24,6 +26,27 @@ typedef unsigned int GLenum;
namespace cv {
namespace v4d {
class V4D;
template <typename ... Args>
class V4DAndArgsInFunctor : public std::function<void(cv::Ptr<V4D>, Args ...)> {
public:
V4DAndArgsInFunctor(cv::Ptr<V4D> window, Args ... args) : std::function<void(cv::Ptr<V4D>, Args ...)>(window, args...) {
}
};
template <typename Tfn, typename ... Args>
class V4DAndFbAndArgsInFunctor : public std::function<void(cv::Ptr<V4D>, cv::UMat&, Args& ...)> {
public:
V4DAndFbAndArgsInFunctor(Tfn fn) : std::function<void(cv::Ptr<V4D>, cv::UMat&, Args& ...)>(fn) {
}
};
template <typename ... Args>
class V4DAndSizeTAndArgsInFunctor : public std::function<void(cv::Ptr<V4D>, size_t&, Args ...)> {
public:
V4DAndSizeTAndArgsInFunctor(std::function<void(cv::Ptr<V4D>, size_t&, Args ...)> fn) : std::function<void(cv::Ptr<V4D>, size_t&, Args ...)>(fn) {
}
};
namespace detail {
typedef cv::ocl::OpenCLExecutionContext CLExecContext_t;
class CLExecScope_t
@ -217,7 +240,24 @@ public:
* directly on the framebuffer.
* @param fn A function object that is passed the framebuffer to be read/manipulated.
*/
void execute(std::function<void(cv::UMat&)> fn);
template <typename Tfn, typename ... Args>
void execute(Tfn fn, Args& ... args) {
run_sync_on_main<2>([this, fn, &args...](){
#ifndef __EMSCRIPTEN__
if(!getCLExecContext().empty()) {
CLExecScope_t clExecScope(getCLExecContext());
FrameBufferContext::GLScope glScope(*this, GL_FRAMEBUFFER);
FrameBufferContext::FrameBufferScope fbScope(*this, framebuffer_);
fn(framebuffer_, args...);
} else
#endif
{
FrameBufferContext::GLScope glScope(*this, GL_FRAMEBUFFER);
FrameBufferContext::FrameBufferScope fbScope(*this, framebuffer_);
fn(framebuffer_, args...);
}
});
}
cv::Vec2f position();
float pixelRatioX();
float pixelRatioY();

@ -19,7 +19,7 @@ namespace detail {
/*!
* Used to setup a nanovg context
*/
class GLContext {
class CV_EXPORTS GLContext {
FrameBufferContext& mainFbContext_;
FrameBufferContext glFbContext_;
public:
@ -34,7 +34,7 @@ public:
* @param fn A function that is passed the size of the framebuffer
* and performs drawing using opengl
*/
void render(std::function<void(const cv::Size&)> fn);
void render(std::function<void()> fn);
FrameBufferContext& fbCtx();
};

@ -19,7 +19,7 @@ namespace detail {
/*!
* Used to setup a nanovg context
*/
class NanoVGContext {
class CV_EXPORTS NanoVGContext {
FrameBufferContext& mainFbContext_;
FrameBufferContext nvgFbContext_;
NVGcontext* context_;
@ -61,7 +61,7 @@ public:
* @param fn A function that is passed the size of the framebuffer
* and performs drawing using cv::viz::nvg
*/
void render(std::function<void(const cv::Size&)> fn);
void render(std::function<void()> fn);
FrameBufferContext& fbCtx();
private:

@ -8,6 +8,7 @@
#include <ostream>
#include <limits>
#include <mutex>
#include <opencv2/core/cvdef.h>
using std::ostream;
using std::stringstream;
@ -16,7 +17,7 @@ using std::map;
using std::chrono::microseconds;
using std::mutex;
struct TimeInfo {
struct CV_EXPORTS TimeInfo {
long totalCnt_ = 0;
long totalTime_ = 0;
long iterCnt_ = 0;
@ -60,7 +61,7 @@ inline std::ostream& operator<<(ostream &os, TimeInfo &ti) {
return os;
}
class TimeTracker {
class CV_EXPORTS TimeTracker {
private:
static TimeTracker *instance_;
mutex mapMtx_;

@ -78,14 +78,22 @@ make_function(T *t)
static thread_local bool sync_run = false;
template<std::size_t Tid>
void run_sync_on_main(std::function<void()> fn) {
CV_Assert(fn);
if(sync_run)
throw std::runtime_error("Encountered nested run_sync_on_main");
sync_run = true;
#ifdef __EMSCRIPTEN__
emscripten_sync_run_in_main_runtime_thread(EM_FUNC_SIG_V, cv::v4d::detail::get_fn_ptr<Tid>(fn));
typedef void* function_t( void* ) ;
function_t* ptr_fun = fn.target<function_t>() ;
//Check that the function object wrapped something callable
CV_Assert( ptr_fun != nullptr );
emscripten_sync_run_in_main_runtime_thread(EM_FUNC_SIG_V, ptr_fun);
#else
fn();
#endif
sync_run = false;
}

@ -18,7 +18,11 @@
#include "detail/threadpool.hpp"
#include "opencv2/v4d/detail/gl.hpp"
#include "opencv2/v4d/detail/framebuffercontext.hpp"
#include "opencv2/v4d/detail/nanovgcontext.hpp"
#include "opencv2/v4d/detail/imguicontext.hpp"
#include "opencv2/v4d/detail/timetracker.hpp"
#include "opencv2/v4d/detail/glcontext.hpp"
#include <iostream>
#include <future>
@ -26,6 +30,8 @@
#include <map>
#include <string>
#include <memory>
#include <vector>
#include <type_traits>
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
@ -38,6 +44,7 @@ using std::string;
struct GLFWwindow;
/*!
* OpenCV namespace
*/
@ -57,6 +64,24 @@ enum AllocateFlags {
* Private namespace
*/
namespace detail {
//https://stackoverflow.com/questions/19961873/test-if-a-lambda-is-stateless#:~:text=As%20per%20the%20Standard%2C%20if,lambda%20is%20stateless%20or%20not.
template <typename T, typename U>
struct helper : helper<T, decltype(&U::operator())>
{};
template <typename T, typename C, typename R, typename... A>
struct helper<T, R(C::*)(A...) const>
{
static const bool value = std::is_convertible<T, R(*)(A...)>::value;
};
template<typename T>
struct is_stateless
{
static const bool value = helper<T,T>::value;
};
class FrameBufferContext;
class CLVAContext;
class NanoVGContext;
@ -71,8 +96,8 @@ template<typename T> std::string int_to_hex( T i )
return stream.str();
}
template<typename T, typename... U> std::string func_id(std::function<T (U ...)> f) {
return int_to_hex((size_t) &f);
template<typename Tfn> std::string func_id(Tfn& fn) {
return int_to_hex((size_t) &fn);
}
}
@ -181,15 +206,24 @@ public:
*/
CV_EXPORTS cv::ogl::Texture2D& texture();
CV_EXPORTS std::string title();
CV_EXPORTS void gl(std::function<void()> fn);
CV_EXPORTS void gl(std::function<void(const cv::Size&)> fn);
/*!
* Execute function object fn inside an opengl context.
* This is how all OpenGL operations should be executed.
* @param fn A function object that is passed the size of the framebuffer
*/
CV_EXPORTS void gl(std::function<void(const cv::Size&)> fn, const uint32_t& idx);
CV_EXPORTS void gl(std::function<void()> fn, const uint32_t& idx);
template <typename Tfn, typename ... Args>
void gl(Tfn fn, Args&& ... args) {
TimeTracker::getInstance()->execute("gl(" + detail::func_id(fn) + ")/" + std::to_string(-1), [this, fn, &args...](){
glCtx(-1).render([=]() {
fn(args...);
});
});
}
template <typename Tfn, typename ... Args>
void gl(const size_t& idx, Tfn fn, Args&& ... args) {
TimeTracker::getInstance()->execute("gl(" + detail::func_id(fn) + ")/" + std::to_string(-1), [this, fn, idx, &args...](){
glCtx(idx).render([=]() {
fn(args...);
});
});
}
/*!
* Execute function object fn inside a framebuffer context.
* The context acquires the framebuffer from OpenGL (either by up-/download or by cl-gl sharing)
@ -197,7 +231,13 @@ public:
* directly on the framebuffer.
* @param fn A function object that is passed the framebuffer to be read/manipulated.
*/
CV_EXPORTS void fb(std::function<void(cv::UMat&)> fn);
template <typename Tfn, typename ... Args>
void fb(Tfn fn, Args& ... args) {
CV_Assert(detail::is_stateless<decltype(fn)>::value);
TimeTracker::getInstance()->execute("fb(" + detail::func_id(fn) + ")", [this, fn, &args...]{
fbCtx().execute(fn, args...);
});
}
/*!
* Execute function object fn inside a nanovg context.
* The context takes care of setting up opengl and nanovg states.
@ -205,8 +245,15 @@ public:
* @param fn A function that is passed the size of the framebuffer
* and performs drawing using cv::viz::nvg
*/
CV_EXPORTS void nvg(std::function<void(const cv::Size&)> fn);
CV_EXPORTS void nvg(std::function<void()> fn);
template <typename Tfn, typename ... Args>
void nvg(Tfn fn, Args&& ... args) {
TimeTracker::getInstance()->execute("nvg(" + detail::func_id(fn) + ")", [this, fn, &args...](){
nvgCtx().render([this, fn, &args...]() {
fn(args...);
});
});
}
CV_EXPORTS void imgui(std::function<void(ImGuiContext* ctx)> fn);
/*!
@ -316,7 +363,7 @@ public:
* Get the current size of the window.
* @return The window size.
*/
CV_EXPORTS cv::Size framebufferSize();
CV_EXPORTS cv::Size fbSize();
/*!
* Set the window size
* @param sz The future size of the window.

@ -249,25 +249,25 @@ static bool iteration(cv::Ptr<V4D> window) {
if (!faceRect.empty() && facemark->fit(down, faceRects, shapes)) {
FaceFeatures features(faceRect, shapes[0], float(down.size().width) / WIDTH);
window->nvg([&features]() {
window->nvg([](FaceFeatures& f) {
//Draw the face oval of the first face
draw_face_oval_mask(features);
});
draw_face_oval_mask(f);
}, features);
window->fb([](cv::UMat &frameBuffer) {
//Convert/Copy the mask
cvtColor(frameBuffer, faceOval, cv::COLOR_BGRA2GRAY);
});
window->nvg([&features]() {
window->nvg([](FaceFeatures& f) {
//Draw eyes eyes and lips areas of the first face
draw_face_eyes_and_lips_mask(features);
});
draw_face_eyes_and_lips_mask(f);
}, features);
window->fb([](cv::UMat &frameBuffer) {
window->fb([](cv::UMat &frameBuffer, cv::UMat& e) {
//Convert/Copy the mask
cvtColor(frameBuffer, eyesAndLipsMaskGrey, cv::COLOR_BGRA2GRAY);
});
cvtColor(frameBuffer, e, cv::COLOR_BGRA2GRAY);
}, eyesAndLipsMaskGrey);
//Create the skin mask
cv::subtract(faceOval, eyesAndLipsMaskGrey, faceSkinMaskGrey);
@ -316,9 +316,9 @@ static bool iteration(cv::Ptr<V4D> window) {
}
//write the result to the framebuffer
window->fb([](cv::UMat &frameBuffer) {
cvtColor(frameOut, frameBuffer, cv::COLOR_BGR2BGRA);
});
window->fb([](cv::UMat &frameBuffer, cv::UMat& f) {
cvtColor(f, frameBuffer, cv::COLOR_BGR2BGRA);
}, frameOut);
window->write();

@ -224,7 +224,7 @@ static void glow_effect(const cv::UMat& src, cv::UMat& dst, const int ksize) {
using namespace cv::v4d;
static bool iteration(cv::Ptr<V4D> window) {
window->once([=](){ window->gl(init_scene);});
window->once([=](){ window->gl(init_scene, window->fbSize());});
//Render using OpenGL
window->gl(render_scene);

@ -44,15 +44,15 @@ int main() {
return false;
//Render "Hello Rainbow!" over the video
win->nvg([hr](const Size& sz) {
win->nvg([](const Size& sz, const string& str) {
using namespace cv::v4d::nvg;
fontSize(40.0f);
fontFace("sans-bold");
fillColor(Scalar(255, 0, 0, 255));
textAlign(NVG_ALIGN_CENTER | NVG_ALIGN_TOP);
text(sz.width / 2.0, sz.height / 2.0, hr.c_str(), hr.c_str() + hr.size());
});
text(sz.width / 2.0, sz.height / 2.0, str.c_str(), str.c_str() + str.size());
}, win->fbSize(), hr);
win->write();

@ -17,16 +17,16 @@ int main() {
//We have to manually resize and color convert the image when using direct frambuffer access.
UMat resized;
UMat converted;
resize(image, resized, window->framebufferSize());
resize(image, resized, window->fbSize());
cvtColor(resized, converted, COLOR_RGB2BGRA);
window->run([converted](Ptr<V4D> win){
//Create a fb context and copy the prepared image to the framebuffer. The fb context
//takes care of retrieving and storing the data on the graphics card (using CL-GL
//interop if available), ready for other contexts to use
win->fb([&](UMat& framebuffer){
converted.copyTo(framebuffer);
});
win->fb([](UMat& framebuffer, const cv::UMat& c){
c.copyTo(framebuffer);
}, converted);
return win->display();
});
}

@ -26,33 +26,33 @@ int main() {
//Execute only once
win->once([win, &image]() {
//Creates a NanoVG context. The wrapped C-functions of NanoVG are available in the namespace cv::v4d::nvg;
win->nvg([&image](const cv::Size sz) {
win->nvg([](Image_t& img) {
using namespace cv::v4d::nvg;
//Create the image and receive a handle.
int handle = createImage(image.filename_.c_str(), NVG_IMAGE_NEAREST);
int handle = createImage(img.filename_.c_str(), NVG_IMAGE_NEAREST);
//Make sure it was created successfully
CV_Assert(handle > 0);
//Query the image size
imageSize(handle, &image.w_, &image.h_);
imageSize(handle, &img.w_, &img.h_);
//Create a simple image pattern with the image dimensions
image.paint_ = imagePattern(0, 0, image.w_, image.h_, 0.0f/180.0f*NVG_PI, handle, 1.0);
});
img.paint_ = imagePattern(0, 0, img.w_, img.h_, 0.0f/180.0f*NVG_PI, handle, 1.0);
}, image);
});
//Creates a NanoVG context to draw the loaded image over again to the screen.
win->nvg([&image](const cv::Size sz) {
win->nvg([](const Image_t& img, const cv::Size& sz) {
using namespace cv::v4d::nvg;
beginPath();
//Scale all further calls to window size
scale(double(sz.width)/image.w_, double(sz.height)/image.h_);
scale(double(sz.width)/img.w_, double(sz.height)/img.h_);
//Create a rounded rectangle with the images dimensions.
//Note that actually this rectangle will have the size of the window
//because of the previous scale call.
roundedRect(0,0, image.w_, image.h_, 50);
roundedRect(0,0, img.w_, img.h_, 50);
//Fill the rounded rectangle with our picture
fillPaint(image.paint_);
fillPaint(img.paint_);
fill();
});
}, image, win->fbSize());
//Displays the framebuffer in the window. Returns false if the windows has been closed.
return win->display();
});

@ -110,11 +110,11 @@ static bool iteration(cv::Ptr<V4D> window) {
circle(rng.uniform(0, sz.width) , rng.uniform(0, sz.height), size / 2.0);
stroke();
}
});
}, window->fbSize());
window->fb([](cv::UMat& frameBuffer){
frameBuffer.copyTo(stars);
});
window->fb([](cv::UMat& frameBuffer, cv::UMat& f){
frameBuffer.copyTo(f);
}, stars);
update_stars = false;
}
@ -129,7 +129,7 @@ static bool iteration(cv::Ptr<V4D> window) {
update_perspective = false;
}
window->nvg([translateY](const cv::Size& sz) {
window->nvg([](const cv::Size& sz, const int32_t& ty) {
using namespace cv::v4d::nvg;
clear();
fontSize(font_size);
@ -138,22 +138,22 @@ static bool iteration(cv::Ptr<V4D> window) {
textAlign(NVG_ALIGN_CENTER | NVG_ALIGN_TOP);
/** only draw lines that are visible **/
translate(0, translateY);
translate(0, ty);
for (size_t i = 0; i < lines.size(); ++i) {
y = (i * font_size);
if (y + translateY < textHeight && y + translateY + font_size > 0) {
if (y + ty < textHeight && y + ty + font_size > 0) {
text(sz.width / 2.0, y, lines[i].c_str(), lines[i].c_str() + lines[i].size());
}
}
});
}, window->fbSize(), translateY);
window->fb([](cv::UMat& framebuffer) {
window->fb([](cv::UMat& framebuffer, cv::UMat& w, cv::UMat& s, cv::Mat& t) {
//Pseudo 3D text effect.
cv::warpPerspective(framebuffer, warped, tm, framebuffer.size(), cv::INTER_LINEAR, cv::BORDER_CONSTANT, cv::Scalar());
cv::warpPerspective(framebuffer, w, t, framebuffer.size(), cv::INTER_LINEAR, cv::BORDER_CONSTANT, cv::Scalar());
//Combine layers
cv::add(stars, warped, framebuffer);
});
cv::add(s, w, framebuffer);
}, warped, stars, tm);
if(-translateY > textHeight) {
//reset the scroll once the text is out of the picture

@ -11,15 +11,15 @@ int main() {
window->run([hw](Ptr<V4D> win){
//Render the text at the center of the screen. Note that you can load you own fonts.
win->nvg([hw](const Size& sz) {
win->nvg([](const Size& sz, const string& str) {
using namespace cv::v4d::nvg;
clear();
fontSize(40.0f);
fontFace("sans-bold");
fillColor(Scalar(255, 0, 0, 255));
textAlign(NVG_ALIGN_CENTER | NVG_ALIGN_TOP);
text(sz.width / 2.0, sz.height / 2.0, hw.c_str(), hw.c_str() + hw.size());
});
text(sz.width / 2.0, sz.height / 2.0, str.c_str(), str.c_str() + str.size());
}, win->fbSize(), hw);
return win->display();
});

@ -24,15 +24,15 @@ int main() {
window->run([&](Ptr<V4D> win) {
//Render the text at the center of the screen using parameters from the GUI.
win->nvg([&](const Size& sz) {
win->nvg([](const Size& sz, const string& str, float s, float c[3]) {
using namespace cv::v4d::nvg;
clear();
fontSize(size);
fontSize(s);
fontFace("sans-bold");
fillColor(Scalar(color[2] * 255, color[1] * 255, color[0] * 255, 255));
fillColor(Scalar(c[2] * 255, c[1] * 255, c[0] * 255, 255));
textAlign(NVG_ALIGN_CENTER | NVG_ALIGN_TOP);
text(sz.width / 2.0, sz.height / 2.0, hw.c_str(), hw.c_str() + hw.size());
});
text(sz.width / 2.0, sz.height / 2.0, str.c_str(), str.c_str() + str.size());
}, win->fbSize(), hw, size, color);
return win->display();
});

@ -230,7 +230,7 @@ using namespace cv::v4d;
static bool iteration(cv::Ptr<V4D> window) {
window->once([=](){
for(size_t i = 0; i < NUMBER_OF_CUBES; ++i)
window->gl([=](const cv::Size sz){ init_scene(sz, i); }, i);
window->gl(i, [](const cv::Size& sz, const size_t& idx){ init_scene(sz, idx); }, window->fbSize(), i);
});
window->gl([](){
@ -241,10 +241,10 @@ static bool iteration(cv::Ptr<V4D> window) {
//Render using multiple OpenGL contexts
for(size_t i = 0; i < NUMBER_OF_CUBES; ++i) {
window->gl([i](){
double pos = (((double(i) / NUMBER_OF_CUBES) * 2.0) - 1) + (1.0 / NUMBER_OF_CUBES);
double angle = sin((double(i) / NUMBER_OF_CUBES) * 2 * M_PI);
render_scene(pos, pos, angle, i);
window->gl(i, [](const size_t idx){
double pos = (((double(idx) / NUMBER_OF_CUBES) * 2.0) - 1) + (1.0 / NUMBER_OF_CUBES);
double angle = sin((double(idx) / NUMBER_OF_CUBES) * 2 * M_PI);
render_scene(pos, pos, angle, idx);
}, i);
}
//To slow for WASM

@ -164,9 +164,9 @@ static bool iteration(cv::Ptr<V4D> window) {
});
//Render using nanovg
window->nvg([hue](const cv::Size &sz) {
draw_color_wheel(sz.width - 300, sz.height - 300, 250.0f, 250.0f, hue);
});
window->nvg([](const cv::Size &sz, const double& h) {
draw_color_wheel(sz.width - 300, sz.height - 300, 250.0f, 250.0f, h);
}, window->fbSize(), hue);
window->write();

@ -406,7 +406,7 @@ static bool iteration(cv::Ptr<V4D> window) {
if(!window->capture())
return false;
static thread_local cv::Size fbSz = window->framebufferSize();
static thread_local cv::Size fbSz = window->fbSize();
//BGRA
static thread_local cv::UMat background, down;
static thread_local cv::UMat foreground(fbSz, CV_8UC4, cv::Scalar::all(0));

@ -212,12 +212,12 @@ static bool iteration(cv::Ptr<V4D> window) {
float cy = tracked.y * HEIGHT_SCALE + (height / 2.0f);
ellipse(cx, cy, width / 2.0f, height / 2.0f);
stroke();
});
}, window->fbSize());
//Put it all together
window->fb([](cv::UMat& frameBuffer){
composite_layers(background, frameBuffer, frameBuffer, BLUR_KERNEL_SIZE);
});
window->fb([](cv::UMat& frameBuffer, cv::UMat& bg){
composite_layers(bg, frameBuffer, frameBuffer, BLUR_KERNEL_SIZE);
}, background);
window->write();

@ -268,12 +268,12 @@ static void setup_gui(cv::Ptr<V4D> window) {
}
static bool iteration(cv::Ptr<V4D> window) {
window->once([=](){ window->gl(init_scene);});
window->once([=](){ window->gl(init_scene, window->fbSize());});
if(!window->capture())
return false;
window->gl(render_scene);
window->gl(render_scene, window->fbSize());
#ifndef __EMSCRIPTEN__
window->fb([](cv::UMat& frameBuffer) {

@ -91,7 +91,7 @@ int main() {
ellipse(rx, ry, ex, ey);
fillPaint(gloss);
fill();
});
}, win->fbSize());
return win->display();
});

@ -90,7 +90,7 @@ int main() {
ellipse(rx, ry, ex, ey);
fillPaint(gloss);
fill();
});
}, win->fbSize());
//Provides the framebuffer as left-off by the nvg context.
win->fb([](UMat& framebuffer) {

@ -34,15 +34,15 @@ int main(int argc, char** argv) {
return false; //end of input video
//Render on top of the video
win->nvg([hv](const Size& sz) {
win->nvg([](const Size& sz, const string& str) {
using namespace cv::v4d::nvg;
fontSize(40.0f);
fontFace("sans-bold");
fillColor(Scalar(255, 0, 0, 255));
textAlign(NVG_ALIGN_CENTER | NVG_ALIGN_TOP);
text(sz.width / 2.0, sz.height / 2.0, hv.c_str(), hv.c_str() + hv.size());
});
text(sz.width / 2.0, sz.height / 2.0, str.c_str(), str.c_str() + str.size());
}, win->fbSize(), hv);
//Write video to the sink (do nothing in case of WebAssembly)
win->write();

@ -5,8 +5,6 @@
#include "opencv2/v4d/v4d.hpp"
#include "opencv2/v4d/detail/framebuffercontext.hpp"
#include "opencv2/v4d/util.hpp"
#include "glcontext.hpp"
#include "nanovgcontext.hpp"
#include "opencv2/core/ocl.hpp"
#include "opencv2/core/opengl.hpp"
#include <exception>
@ -631,24 +629,6 @@ void FrameBufferContext::copyFrom(const cv::UMat& src) {
});
}
void FrameBufferContext::execute(std::function<void(cv::UMat&)> fn) {
run_sync_on_main<2>([&,this](){
#ifndef __EMSCRIPTEN__
if(!getCLExecContext().empty()) {
CLExecScope_t clExecScope(getCLExecContext());
FrameBufferContext::GLScope glScope(*this, GL_FRAMEBUFFER);
FrameBufferContext::FrameBufferScope fbScope(*this, framebuffer_);
fn(framebuffer_);
} else
#endif
{
FrameBufferContext::GLScope glScope(*this, GL_FRAMEBUFFER);
FrameBufferContext::FrameBufferScope fbScope(*this, framebuffer_);
fn(framebuffer_);
}
});
}
cv::ogl::Texture2D& FrameBufferContext::getTexture2D() {
return *texture_;
}

@ -3,7 +3,7 @@
// of this distribution and at http://opencv.org/license.html.
// Copyright Amir Hassan (kallaballa) <amir@viel-zu.org>
#include "glcontext.hpp"
#include "opencv2/v4d/detail/glcontext.hpp"
#include "opencv2/v4d/detail/gl.hpp"
namespace cv {
@ -18,8 +18,8 @@ GLContext::GLContext(FrameBufferContext& fbContext) :
#endif
}
void GLContext::render(std::function<void(const cv::Size&)> fn) {
run_sync_on_main<15>([&,this](){
void GLContext::render(std::function<void()> fn) {
run_sync_on_main<15>([this, fn](){
#ifndef __EMSCRIPTEN__
if(!fbCtx().isShared()) {
UMat tmp;
@ -38,7 +38,7 @@ void GLContext::render(std::function<void(const cv::Size&)> fn) {
GL_CHECK(glClear(GL_COLOR_BUFFER_BIT));
GL_CHECK(glClearColor(cColor[0], cColor[1], cColor[2], cColor[3]));
#endif
fn(fbCtx().size());
fn();
}
if(!fbCtx().isShared()) {
#ifdef __EMSCRIPTEN__

@ -3,7 +3,7 @@
// of this distribution and at http://opencv.org/license.html.
// Copyright Amir Hassan (kallaballa) <amir@viel-zu.org>
#include "nanovgcontext.hpp"
#include "opencv2/v4d/detail/nanovgcontext.hpp"
#include "opencv2/v4d/nvg.hpp"
#include "opencv2/v4d/detail/gl.hpp"
#include "nanovg_gl.h"
@ -41,7 +41,7 @@ NanoVGContext::NanoVGContext(FrameBufferContext& fbContext) :
});
}
void NanoVGContext::render(std::function<void(const cv::Size&)> fn) {
void NanoVGContext::render(std::function<void()> fn) {
run_sync_on_main<14>([this, fn]() {
#ifndef __EMSCRIPTEN__
if (!fbCtx().isShared()) {
@ -59,7 +59,7 @@ void NanoVGContext::render(std::function<void(const cv::Size&)> fn) {
#endif
NanoVGContext::Scope nvgScope(*this);
cv::v4d::nvg::detail::NVG::initializeContext(context_);
fn(fbCtx().size());
fn();
}
if (!fbCtx().isShared()) {
#ifdef __EMSCRIPTEN__

@ -5,7 +5,7 @@
* Author: elchaschab
*/
#include "timetracker.hpp"
#include "opencv2/v4d/detail/timetracker.hpp"
TimeTracker* TimeTracker::instance_;

@ -6,11 +6,10 @@
#include "opencv2/v4d/v4d.hpp"
#include "opencv2/v4d/detail/framebuffercontext.hpp"
#include "detail/clvacontext.hpp"
#include "detail/nanovgcontext.hpp"
#include "detail/glcontext.hpp"
#include "detail/timetracker.hpp"
#include <sstream>
#include <algorithm>
#include <opencv2/core.hpp>
#include <vector>
namespace cv {
namespace v4d {
@ -156,59 +155,6 @@ size_t V4D::numGlCtx() {
return std::max(off_t(0), off_t(glContexts_.size()) - 1);
}
void V4D::gl(std::function<void()> fn) {
TimeTracker::getInstance()->execute("gl(" + detail::func_id(fn) + ")/" + std::to_string(-1), [this, fn](){
glCtx(-1).render([=](const cv::Size& sz) {
CV_UNUSED(sz);
fn();
});
});
}
void V4D::gl(std::function<void(const cv::Size&)> fn) {
TimeTracker::getInstance()->execute("gl(" + detail::func_id(fn) + ")/" + std::to_string(-1), [this, fn](){
glCtx(-1).render(fn);
});
}
void V4D::gl(std::function<void()> fn, const uint32_t& idx) {
TimeTracker::getInstance()->execute("gl(" + detail::func_id(fn) + ")/" + std::to_string(idx), [this, fn, idx](){
glCtx(idx).render([=](const cv::Size& sz) {
CV_UNUSED(sz);
fn();
});
});
}
void V4D::gl(std::function<void(const cv::Size&)> fn, const uint32_t& idx) {
TimeTracker::getInstance()->execute("gl(" + detail::func_id(fn) + ")/" + std::to_string(idx), [this, fn, idx](){
glCtx(idx).render(fn);
});
}
void V4D::fb(std::function<void(cv::UMat&)> fn) {
TimeTracker::getInstance()->execute("fb(" + detail::func_id(fn) + ")", [this, fn](){
fbCtx().execute(fn);
});
}
void V4D::nvg(std::function<void()> fn) {
TimeTracker::getInstance()->execute("nvg(" + detail::func_id(fn) + ")", [this, fn](){
nvgCtx().render([fn](const cv::Size& sz) {
CV_UNUSED(sz);
fn();
});
});
}
void V4D::nvg(std::function<void(const cv::Size&)> fn) {
TimeTracker::getInstance()->execute("nvg(" + detail::func_id(fn) + ")", [this, fn](){
nvgCtx().render(fn);
});
}
void V4D::imgui(std::function<void(ImGuiContext* ctx)> fn) {
TimeTracker::getInstance()->execute("imgui(" + detail::func_id(fn) + ")", [this, fn](){
@ -355,18 +301,19 @@ void V4D::feed(cv::InputArray in) {
in.copyTo(videoFrame);
}, frame);
fb([&frame](cv::UMat& framebuffer){
frame.copyTo(framebuffer);
});
//V4DAndFbAndArgsInFunctor<cv::UMat&> fn();
fb([](cv::UMat& fb, cv::UMat& f) {
f.copyTo(fb);
}, frame);
});
}
cv::_InputArray V4D::fetch() {
cv::UMat frame;
TimeTracker::getInstance()->execute("copyTo", [this, &frame](){
fb([frame](cv::UMat& framebuffer){
framebuffer.copyTo(frame);
});
fb([](cv::UMat& fb, cv::UMat& f) {
fb.copyTo(f);
}, frame);
});
return frame;
}
@ -426,9 +373,9 @@ bool V4D::capture(std::function<void(cv::UMat&)> fn) {
return v->clvaCtx().capture(func, frame);
}, this, fn, nextReaderFrame_);
fb([this](cv::UMat& frameBuffer){
currentReaderFrame_.copyTo(frameBuffer);
});
fb([](cv::UMat& fb, cv::UMat& f){
f.copyTo(fb);
}, this->currentReaderFrame_);
});
return res;
}
@ -465,9 +412,9 @@ void V4D::write(std::function<void(const cv::UMat&)> fn) {
if (futureWriter_.valid())
futureWriter_.get();
fb([this](cv::UMat& frameBuffer){
frameBuffer.copyTo(currentWriterFrame_);
});
fb([](cv::UMat& fb, cv::UMat& f){
fb.copyTo(f);
}, currentWriterFrame_);
futureWriter_ = thread_pool_.enqueue([](V4D* v, std::function<void(const UMat&)> func, cv::UMat& frame) {
v->clvaCtx().write(func, frame);
@ -495,7 +442,7 @@ float V4D::pixelRatioY() {
return fbCtx().pixelRatioY();
}
cv::Size V4D::framebufferSize() {
cv::Size V4D::fbSize() {
return fbCtx().size();
}

Loading…
Cancel
Save