diff --git a/modules/gapi/include/opencv2/gapi/render/render.hpp b/modules/gapi/include/opencv2/gapi/render/render.hpp
index 4f219f9e1b..fe9daac333 100644
--- a/modules/gapi/include/opencv2/gapi/render/render.hpp
+++ b/modules/gapi/include/opencv2/gapi/render/render.hpp
@@ -22,7 +22,6 @@ namespace cv
 {
 namespace gapi
 {
-
 namespace wip
 {
 namespace draw
@@ -122,7 +121,7 @@ struct Poly
     cv::Scalar             color;   //!< The line color
     int                    thick;   //!< The thickness of line
     int                    lt;      //!< The Type of the line. See #LineTypes
-    int                    shift;   //!< The number of fractional bits in the point coordinates
+    int                    shift;   //!< The number of fractional bits in the point coordinate
 };
 
 using Prim  = util::variant
diff --git a/modules/gapi/src/api/render.cpp b/modules/gapi/src/api/render.cpp
index f21c2e1ab4..f9c61124cc 100644
--- a/modules/gapi/src/api/render.cpp
+++ b/modules/gapi/src/api/render.cpp
@@ -4,8 +4,8 @@
 
 #include "api/render_priv.hpp"
 
-void cv::gapi::wip::draw::render(cv::Mat &bgr,
-                                 const cv::gapi::wip::draw::Prims &prims,
+void cv::gapi::wip::draw::render(cv::Mat& bgr,
+                                 const cv::gapi::wip::draw::Prims& prims,
                                  cv::GCompileArgs&& args)
 {
     cv::GMat in;
@@ -16,9 +16,9 @@ void cv::gapi::wip::draw::render(cv::Mat &bgr,
     comp.apply(cv::gin(bgr, prims), cv::gout(bgr), std::move(args));
 }
 
-void cv::gapi::wip::draw::render(cv::Mat &y_plane,
-                                 cv::Mat &uv_plane,
-                                 const Prims &prims,
+void cv::gapi::wip::draw::render(cv::Mat& y_plane,
+                                 cv::Mat& uv_plane,
+                                 const Prims& prims,
                                  cv::GCompileArgs&& args)
 {
     cv::GMat y_in, uv_in, y_out, uv_out;
@@ -30,22 +30,28 @@ void cv::gapi::wip::draw::render(cv::Mat &y_plane,
                cv::gout(y_plane, uv_plane), std::move(args));
 }
 
-void cv::gapi::wip::draw::BGR2NV12(const cv::Mat &bgr,
-                                   cv::Mat &y_plane,
-                                   cv::Mat &uv_plane)
+void cv::gapi::wip::draw::cvtYUVToNV12(const cv::Mat& yuv,
+                                       cv::Mat& y,
+                                       cv::Mat& uv)
 {
-    GAPI_Assert(bgr.size().width  % 2 == 0);
-    GAPI_Assert(bgr.size().height % 2 == 0);
-
-    cv::Mat yuv;
-    cvtColor(bgr, yuv, cv::COLOR_BGR2YUV);
+    GAPI_Assert(yuv.size().width  % 2 == 0);
+    GAPI_Assert(yuv.size().height % 2 == 0);
 
     std::vector<cv::Mat> chs(3);
     cv::split(yuv, chs);
-    y_plane = chs[0];
+    y = chs[0];
+
+    cv::merge(std::vector<cv::Mat>{chs[1], chs[2]}, uv);
+    cv::resize(uv, uv, uv.size() / 2, cv::INTER_LINEAR);
+}
 
-    cv::merge(std::vector<cv::Mat>{chs[1], chs[2]}, uv_plane);
-    cv::resize(uv_plane, uv_plane, uv_plane.size() / 2, cv::INTER_LINEAR);
+void cv::gapi::wip::draw::cvtNV12ToYUV(const cv::Mat& y,
+                                       const cv::Mat& uv,
+                                       cv::Mat& yuv)
+{
+    cv::Mat upsample_uv;
+    cv::resize(uv, upsample_uv, uv.size() * 2, cv::INTER_LINEAR);
+    cv::merge(std::vector<cv::Mat>{y, upsample_uv}, yuv);
 }
 
 namespace cv
diff --git a/modules/gapi/src/api/render_ocv.cpp b/modules/gapi/src/api/render_ocv.cpp
index ecc1c81eb0..a57707f0bb 100644
--- a/modules/gapi/src/api/render_ocv.cpp
+++ b/modules/gapi/src/api/render_ocv.cpp
@@ -7,37 +7,32 @@ namespace cv
 {
 namespace gapi
 {
-
-namespace ocv
-{
-} // namespace ocv
-
 namespace wip
 {
 namespace draw
 {
 
-void mosaic(cv::Mat mat, const cv::Rect &rect, int cellSz);
-void image(cv::Mat mat, cv::Point org, cv::Mat img, cv::Mat alpha);
-void poly(cv::Mat mat, std::vector<cv::Point>, cv::Scalar color, int lt, int shift);
-
-void mosaic(cv::Mat mat, const cv::Rect &rect, int cellSz)
+// FIXME Support `decim` mosaic parameter
+inline void mosaic(cv::Mat& mat, const cv::Rect &rect, int cellSz)
 {
     cv::Mat msc_roi = mat(rect);
     int crop_x = msc_roi.cols - msc_roi.cols % cellSz;
     int crop_y = msc_roi.rows - msc_roi.rows % cellSz;
 
-    for(int i = 0; i < crop_y; i += cellSz )
+    for(int i = 0; i < crop_y; i += cellSz ) {
         for(int j = 0; j < crop_x; j += cellSz) {
             auto cell_roi = msc_roi(cv::Rect(j, i, cellSz, cellSz));
             cell_roi = cv::mean(cell_roi);
         }
-
+    }
 };
 
-void image(cv::Mat mat, cv::Point org, cv::Mat img, cv::Mat alpha)
+inline void image(cv::Mat& mat,
+                  const cv::Point& org,
+                  const cv::Mat& img,
+                  const cv::Mat& alpha)
 {
-    auto roi = mat(cv::Rect(org.x, org.y, img.size().width, img.size().height));
+    auto roi = mat(cv::Rect(org, img.size()));
     cv::Mat img32f_w;
     cv::merge(std::vector<cv::Mat>(3, alpha), img32f_w);
 
@@ -45,6 +40,7 @@ void image(cv::Mat mat, cv::Point org, cv::Mat img, cv::Mat alpha)
     roi32f_w -= img32f_w;
 
     cv::Mat img32f, roi32f;
+
     img.convertTo(img32f, CV_32F, 1.0/255);
     roi.convertTo(roi32f, CV_32F, 1.0/255);
 
@@ -55,10 +51,11 @@ void image(cv::Mat mat, cv::Point org, cv::Mat img, cv::Mat alpha)
     roi32f.convertTo(roi, CV_8U, 255.0);
 };
 
-void poly(cv::Mat mat, std::vector<cv::Point> points, cv::Scalar color, int lt, int shift)
+inline void poly(cv::Mat& mat,
+                 const cv::gapi::wip::draw::Poly& pp)
 {
-    std::vector<std::vector<cv::Point>> pp{points};
-    cv::fillPoly(mat, pp, color, lt, shift);
+    std::vector<std::vector<cv::Point>> points{pp.points};
+    cv::fillPoly(mat, points, pp.color, pp.lt, pp.shift);
 };
 
 struct BGR2YUVConverter
@@ -92,60 +89,60 @@ void drawPrimitivesOCV(cv::Mat &in, const Prims &prims)
         {
             case Prim::index_of<Rect>():
             {
-                const auto& t_p = cv::util::get<Rect>(p);
-                const auto color = converter.cvtColor(t_p.color);
-                cv::rectangle(in, t_p.rect, color , t_p.thick, t_p.lt, t_p.shift);
+                const auto& rp = cv::util::get<Rect>(p);
+                const auto color = converter.cvtColor(rp.color);
+                cv::rectangle(in, rp.rect, color , rp.thick);
                 break;
             }
 
             case Prim::index_of<Text>():
             {
-                const auto& t_p = cv::util::get<Text>(p);
-                const auto color = converter.cvtColor(t_p.color);
-                cv::putText(in, t_p.text, t_p.org, t_p.ff, t_p.fs,
-                            color, t_p.thick, t_p.lt, t_p.bottom_left_origin);
+                const auto& tp = cv::util::get<Text>(p);
+                const auto color = converter.cvtColor(tp.color);
+                cv::putText(in, tp.text, tp.org, tp.ff, tp.fs, color, tp.thick, tp.lt, tp.bottom_left_origin);
                 break;
             }
 
             case Prim::index_of<Circle>():
             {
-                const auto& c_p = cv::util::get<Circle>(p);
-                const auto color = converter.cvtColor(c_p.color);
-                cv::circle(in, c_p.center, c_p.radius, color, c_p.thick, c_p.lt, c_p.shift);
+                const auto& cp = cv::util::get<Circle>(p);
+                const auto color = converter.cvtColor(cp.color);
+                cv::circle(in, cp.center, cp.radius, color, cp.thick);
                 break;
             }
 
             case Prim::index_of<Line>():
             {
-                const auto& l_p = cv::util::get<Line>(p);
-                const auto color = converter.cvtColor(l_p.color);
-                cv::line(in, l_p.pt1, l_p.pt2, color, l_p.thick, l_p.lt, l_p.shift);
+                const auto& lp = cv::util::get<Line>(p);
+                const auto color = converter.cvtColor(lp.color);
+                cv::line(in, lp.pt1, lp.pt2, color, lp.thick);
                 break;
             }
 
             case Prim::index_of<Mosaic>():
             {
-                const auto& l_p = cv::util::get<Mosaic>(p);
-                mosaic(in, l_p.mos, l_p.cellSz);
+                const auto& mp = cv::util::get<Mosaic>(p);
+                GAPI_Assert(mp.decim == 0 && "Only decim = 0 supported now");
+                mosaic(in, mp.mos, mp.cellSz);
                 break;
             }
 
             case Prim::index_of<Image>():
             {
-                const auto& i_p = cv::util::get<Image>(p);
+                const auto& ip = cv::util::get<Image>(p);
 
                 cv::Mat img;
-                converter.cvtImg(i_p.img, img);
+                converter.cvtImg(ip.img, img);
 
-                image(in, i_p.org, img, i_p.alpha);
+                image(in, ip.org, img, ip.alpha);
                 break;
             }
 
             case Prim::index_of<Poly>():
             {
-                const auto& p_p = cv::util::get<Poly>(p);
-                const auto color = converter.cvtColor(p_p.color);
-                poly(in, p_p.points, color, p_p.lt, p_p.shift);
+                auto pp = cv::util::get<Poly>(p);
+                pp.color = converter.cvtColor(pp.color);
+                poly(in, pp);
                 break;
             }
 
diff --git a/modules/gapi/src/api/render_priv.hpp b/modules/gapi/src/api/render_priv.hpp
index ac29a45064..fa0cb97dfe 100644
--- a/modules/gapi/src/api/render_priv.hpp
+++ b/modules/gapi/src/api/render_priv.hpp
@@ -20,7 +20,8 @@ namespace draw
 {
 
 // FIXME only for tests
-GAPI_EXPORTS void BGR2NV12(const cv::Mat& bgr, cv::Mat& y_plane, cv::Mat& uv_plane);
+GAPI_EXPORTS void cvtNV12ToYUV(const cv::Mat& y, const cv::Mat& uv, cv::Mat& yuv);
+GAPI_EXPORTS void cvtYUVToNV12(const cv::Mat& yuv, cv::Mat& y, cv::Mat& uv);
 
 } // namespace draw
 } // namespace wip
diff --git a/modules/gapi/src/backends/render/grenderocv.cpp b/modules/gapi/src/backends/render/grenderocv.cpp
index c549ec7854..47bf8f1e0f 100644
--- a/modules/gapi/src/backends/render/grenderocv.cpp
+++ b/modules/gapi/src/backends/render/grenderocv.cpp
@@ -5,7 +5,7 @@
 
 #include <opencv2/gapi/cpu/gcpukernel.hpp>
 
-GAPI_RENDER_OCV_KERNEL(RenderBGRImpl, cv::gapi::wip::draw::GRenderBGR)
+GAPI_RENDER_OCV_KERNEL(RenderBGROCVImpl, cv::gapi::wip::draw::GRenderBGR)
 {
     static void run(const cv::Mat& in, const cv::gapi::wip::draw::Prims& prims, cv::Mat& out)
     {
@@ -20,7 +20,7 @@ GAPI_RENDER_OCV_KERNEL(RenderBGRImpl, cv::gapi::wip::draw::GRenderBGR)
     }
 };
 
-GAPI_RENDER_OCV_KERNEL(RenderNV12Impl, cv::gapi::wip::draw::GRenderNV12)
+GAPI_RENDER_OCV_KERNEL(RenderNV12OCVImpl, cv::gapi::wip::draw::GRenderNV12)
 {
     static void run(const cv::Mat& in_y,
                     const cv::Mat& in_uv,
@@ -76,6 +76,6 @@ GAPI_RENDER_OCV_KERNEL(RenderNV12Impl, cv::gapi::wip::draw::GRenderNV12)
 
 cv::gapi::GKernelPackage cv::gapi::render::ocv::kernels()
 {
-    const static auto pkg = cv::gapi::kernels<RenderBGRImpl, RenderNV12Impl>();
+    const static auto pkg = cv::gapi::kernels<RenderBGROCVImpl, RenderNV12OCVImpl>();
     return pkg;
 }
diff --git a/modules/gapi/src/backends/render/grenderocvbackend.cpp b/modules/gapi/src/backends/render/grenderocvbackend.cpp
index dbe24f3dc2..aad52c221c 100644
--- a/modules/gapi/src/backends/render/grenderocvbackend.cpp
+++ b/modules/gapi/src/backends/render/grenderocvbackend.cpp
@@ -120,7 +120,6 @@ namespace {
                                   const ade::NodeHandle &op_node,
                                   const cv::GKernelImpl &impl) override {
             GRenderModel rm(gr);
-            //auto render_impl = cv::util::any_cast<cv::gapi::render::ocv::KImpl>(impl.opaque);
             auto render_impl = cv::util::any_cast<cv::GCPUKernel>(impl.opaque);
             rm.metadata(op_node).set(cv::gimpl::render::ocv::RenderUnit{render_impl});
         }
diff --git a/modules/gapi/test/common/gapi_render_tests.cpp b/modules/gapi/test/common/gapi_render_tests.cpp
index 8e845e6f5a..81f7c5b86e 100644
--- a/modules/gapi/test/common/gapi_render_tests.cpp
+++ b/modules/gapi/test/common/gapi_render_tests.cpp
@@ -2,8 +2,55 @@
 // It is subject to the license terms in the LICENSE file found in the top-level directory
 // of this distribution and at http://opencv.org/license.html.
 //
-// Copyright (C) 2018 Intel Corporation
+// Copyright (C) 2019 Intel Corporation
 
 
 #include "../test_precomp.hpp"
-#include "gapi_render_tests_inl.hpp"
+#include "gapi_render_tests.hpp"
+
+namespace opencv_test
+{
+
+cv::Scalar cvtBGRToYUVC(const cv::Scalar& bgr)
+{
+    double y = bgr[2] *  0.299000 + bgr[1] *  0.587000 + bgr[0] *  0.114000;
+    double u = bgr[2] * -0.168736 + bgr[1] * -0.331264 + bgr[0] *  0.500000 + 128;
+    double v = bgr[2] *  0.500000 + bgr[1] * -0.418688 + bgr[0] * -0.081312 + 128;
+    return {y, u, v};
+}
+
+void drawMosaicRef(const cv::Mat& mat, const cv::Rect &rect, int cellSz)
+{
+    cv::Mat msc_roi = mat(rect);
+    int crop_x = msc_roi.cols - msc_roi.cols % cellSz;
+    int crop_y = msc_roi.rows - msc_roi.rows % cellSz;
+
+    for(int i = 0; i < crop_y; i += cellSz ) {
+        for(int j = 0; j < crop_x; j += cellSz) {
+            auto cell_roi = msc_roi(cv::Rect(j, i, cellSz, cellSz));
+            cell_roi = cv::mean(cell_roi);
+        }
+    }
+}
+
+void blendImageRef(cv::Mat& mat, const cv::Point& org, const cv::Mat& img, const cv::Mat& alpha)
+{
+    auto roi = mat(cv::Rect(org, img.size()));
+    cv::Mat img32f_w;
+    cv::merge(std::vector<cv::Mat>(3, alpha), img32f_w);
+
+    cv::Mat roi32f_w(roi.size(), CV_32FC3, cv::Scalar::all(1.0));
+    roi32f_w -= img32f_w;
+
+    cv::Mat img32f, roi32f;
+    img.convertTo(img32f, CV_32F, 1.0/255);
+    roi.convertTo(roi32f, CV_32F, 1.0/255);
+
+    cv::multiply(img32f, img32f_w, img32f);
+    cv::multiply(roi32f, roi32f_w, roi32f);
+    roi32f += img32f;
+
+    roi32f.convertTo(roi, CV_8U, 255.0);
+};
+
+} // namespace opencv_test
diff --git a/modules/gapi/test/common/gapi_render_tests.hpp b/modules/gapi/test/common/gapi_render_tests.hpp
index 29b7235db3..346fd531ec 100644
--- a/modules/gapi/test/common/gapi_render_tests.hpp
+++ b/modules/gapi/test/common/gapi_render_tests.hpp
@@ -9,107 +9,129 @@
 #define OPENCV_GAPI_RENDER_TESTS_HPP
 
 #include "gapi_tests_common.hpp"
-#include "api/render_priv.hpp"
-#include "api/render_ocv.hpp"
 
-#define rect1 Prim{cv::gapi::wip::draw::Rect{cv::Rect{101, 101, 199, 199}, cv::Scalar{153, 172, 58},  1, LINE_8, 0}}
-#define rect2 Prim{cv::gapi::wip::draw::Rect{cv::Rect{100, 100, 199, 199}, cv::Scalar{153, 172, 58},  1, LINE_8, 0}}
-#define rect3 Prim{cv::gapi::wip::draw::Rect{cv::Rect{0  , 0  , 199, 199}, cv::Scalar{153, 172, 58},  1, LINE_8, 0}}
-#define rect4 Prim{cv::gapi::wip::draw::Rect{cv::Rect{100, 100, 0, 199  }, cv::Scalar{153, 172, 58},  1,  LINE_8, 0}}
-#define rect5 Prim{cv::gapi::wip::draw::Rect{cv::Rect{0  , -1 , 199, 199}, cv::Scalar{153, 172, 58},  1,  LINE_8, 0}}
-#define rect6 Prim{cv::gapi::wip::draw::Rect{cv::Rect{100, 100, 199, 199}, cv::Scalar{153, 172, 58},  10, LINE_8, 0}}
-#define rect7 Prim{cv::gapi::wip::draw::Rect{cv::Rect{100, 100, 200, 200}, cv::Scalar{153, 172, 58},  1, LINE_8, 0}}
-#define box1  Prim{cv::gapi::wip::draw::Rect{cv::Rect{101, 101, 200, 200}, cv::Scalar{153, 172, 58}, -1, LINE_8, 0}}
-#define box2  Prim{cv::gapi::wip::draw::Rect{cv::Rect{100, 100, 199, 199}, cv::Scalar{153, 172, 58},  -1, LINE_8, 0}}
-#define rects Prims{rect1, rect2, rect3, rect4, rect5, rect6, rect7, box1, box2}
-
-#define circle1 Prim{cv::gapi::wip::draw::Circle{cv::Point{200, 200}, 100, cv::Scalar{153, 172, 58}, 1, LINE_8, 0}}
-#define circle2 Prim{cv::gapi::wip::draw::Circle{cv::Point{10, 30}  , 2  , cv::Scalar{153, 172, 58}, 1, LINE_8, 0}}
-#define circle3 Prim{cv::gapi::wip::draw::Circle{cv::Point{75, 100} , 50 , cv::Scalar{153, 172, 58}, 5, LINE_8, 0}}
-#define circles Prims{circle1, circle2, circle3}
-
-#define line1 Prim{cv::gapi::wip::draw::Line{cv::Point{50, 50}, cv::Point{250, 200}, cv::Scalar{153, 172, 58}, 1, LINE_8, 0}}
-#define line2 Prim{cv::gapi::wip::draw::Line{cv::Point{51, 51}, cv::Point{51, 100}, cv::Scalar{153, 172, 58}, 1, LINE_8, 0}}
-#define lines Prims{line1, line2}
-
-#define mosaic1 Prim{cv::gapi::wip::draw::Mosaic{cv::Rect{100, 100, 200, 200}, 5, 0}}
-#define mosaics Prims{mosaic1}
-
-#define image1 Prim{cv::gapi::wip::draw::Image{cv::Point(100, 100), cv::Mat(cv::Size(200, 200), CV_8UC3, cv::Scalar::all(255)),\
-                                                                    cv::Mat(cv::Size(200, 200), CV_32FC1, cv::Scalar::all(1))}}
-
-#define image2 Prim{cv::gapi::wip::draw::Image{cv::Point(100, 100), cv::Mat(cv::Size(200, 200), CV_8UC3, cv::Scalar::all(255)),\
-                                                                    cv::Mat(cv::Size(200, 200), CV_32FC1, cv::Scalar::all(0.5))}}
+namespace opencv_test
+{
 
-#define image3 Prim{cv::gapi::wip::draw::Image{cv::Point(100, 100), cv::Mat(cv::Size(200, 200), CV_8UC3, cv::Scalar::all(255)),\
-                                                                    cv::Mat(cv::Size(200, 200), CV_32FC1, cv::Scalar::all(0.0))}}
+template<typename ...SpecificParams>
+struct RenderParams : public Params<SpecificParams...>
+{
+    using common_params_t = std::tuple<cv::Size>;
+    using specific_params_t = std::tuple<SpecificParams...>;
+    using params_t = std::tuple<cv::Size, SpecificParams...>;
 
-#define images Prims{image1, image2, image3}
+    static constexpr const size_t common_params_size = std::tuple_size<common_params_t>::value;
+    static constexpr const size_t specific_params_size = std::tuple_size<specific_params_t>::value;
 
-#define polygon1 Prim{cv::gapi::wip::draw::Poly{ {cv::Point{100, 100}, cv::Point{50, 200}, cv::Point{200, 30}, cv::Point{150, 50} }, cv::Scalar{153, 172, 58}, 1, LINE_8, 0} }
-#define polygons Prims{polygon1}
+    template<size_t I>
+    static const typename std::tuple_element<I, common_params_t>::type&
+    getCommon(const params_t& t)
+    {
+        static_assert(I < common_params_size, "Index out of range");
+        return std::get<I>(t);
+    }
 
-#define text1 Prim{cv::gapi::wip::draw::Text{"TheBrownFoxJump", cv::Point{100, 100}, FONT_HERSHEY_SIMPLEX, 2, cv::Scalar{102, 178, 240}, 1, LINE_8, false} }
-#define texts Prims{text1}
+    template<size_t I>
+    static const typename std::tuple_element<I, specific_params_t>::type&
+    getSpecific(const params_t& t)
+    {
+        static_assert(specific_params_size > 0,
+            "Impossible to call this function: no specific parameters specified");
+        static_assert(I < specific_params_size, "Index out of range");
+        return std::get<common_params_size + I>(t);
+    }
+};
 
-namespace opencv_test
+template<typename ...SpecificParams>
+struct RenderTestBase : public TestWithParam<typename RenderParams<SpecificParams...>::params_t>
 {
+    using AllParams = RenderParams<SpecificParams...>;
 
-using Prims = cv::gapi::wip::draw::Prims;
-using Prim  = cv::gapi::wip::draw::Prim;
-
-template<class T>
-class RenderWithParam : public TestWithParam<T>
-{
-protected:
-    void Init()
+    // Get common (pre-defined) parameter value by index
+    template<size_t I>
+    inline auto getCommonParam() const
+        -> decltype(AllParams::template getCommon<I>(this->GetParam()))
     {
-        MatType type = CV_8UC3;
-        mat_ocv.create(sz, type);
-        mat_gapi.create(sz, type);
-        cv::randu(mat_ocv, cv::Scalar::all(0), cv::Scalar::all(255));
-        mat_ocv.copyTo(mat_gapi);
+        return AllParams::template getCommon<I>(this->GetParam());
     }
 
-    cv::Size sz;
-    std::vector<cv::gapi::wip::draw::Prim> prims;
-    cv::gapi::GKernelPackage pkg;
+    // Get specific (user-defined) parameter value by index
+    template<size_t I>
+    inline auto getSpecificParam() const
+        -> decltype(AllParams::template getSpecific<I>(this->GetParam()))
+    {
+        return AllParams::template getSpecific<I>(this->GetParam());
+    }
 
-    cv::Mat y_mat_ocv, uv_mat_ocv, y_mat_gapi, uv_mat_gapi, mat_ocv, mat_gapi;
+    cv::Size sz_ = getCommonParam<0>();
 };
 
-using TestArgs = std::tuple<cv::Size,cv::gapi::wip::draw::Prims>;
-
-struct RenderNV12 : public RenderWithParam<TestArgs>
+template <typename ...Args>
+class RenderBGRTestBase : public RenderTestBase<Args...>
 {
-    void ComputeRef()
+protected:
+    void Init(const cv::Size& sz)
     {
-        cv::gapi::wip::draw::BGR2NV12(mat_ocv, y_mat_ocv, uv_mat_ocv);
-
-        // NV12 -> YUV
-        cv::Mat upsample_uv, yuv;
-        cv::resize(uv_mat_ocv, upsample_uv, uv_mat_ocv.size() * 2, cv::INTER_LINEAR);
-        cv::merge(std::vector<cv::Mat>{y_mat_ocv, upsample_uv}, yuv);
+        MatType type = CV_8UC3;
 
-        cv::gapi::wip::draw::drawPrimitivesOCVYUV(yuv, prims);
+        ref_mat.create(sz, type);
+        gapi_mat.create(sz, type);
 
-        // YUV -> NV12
-        std::vector<cv::Mat> chs(3);
-        cv::split(yuv, chs);
-        cv::merge(std::vector<cv::Mat>{chs[1], chs[2]}, uv_mat_ocv);
-        y_mat_ocv = chs[0];
-        cv::resize(uv_mat_ocv, uv_mat_ocv, uv_mat_ocv.size() / 2, cv::INTER_LINEAR);
+        cv::randu(ref_mat, cv::Scalar::all(0), cv::Scalar::all(255));
+        ref_mat.copyTo(gapi_mat);
     }
+
+    cv::Mat gapi_mat, ref_mat;
 };
 
-struct RenderBGR : public RenderWithParam<TestArgs>
+template <typename ...Args>
+class RenderNV12TestBase : public RenderTestBase<Args...>
 {
-    void ComputeRef()
+protected:
+    void Init(const cv::Size& sz)
     {
-        cv::gapi::wip::draw::drawPrimitivesOCVBGR(mat_ocv, prims);
+        auto create_rand_mats = [](const cv::Size& size, MatType type, cv::Mat& ref_mat, cv::Mat& gapi_mat) {
+            ref_mat.create(size, type);
+            cv::randu(ref_mat, cv::Scalar::all(0), cv::Scalar::all(255));
+            ref_mat.copyTo(gapi_mat);
+        };
+
+        create_rand_mats(sz,     CV_8UC1, y_ref_mat  , y_gapi_mat);
+        create_rand_mats(sz / 2, CV_8UC2, uv_ref_mat , uv_gapi_mat);
     }
+
+    cv::Mat y_ref_mat, uv_ref_mat, y_gapi_mat, uv_gapi_mat;
+};
+
+cv::Scalar cvtBGRToYUVC(const cv::Scalar& bgr);
+void drawMosaicRef(const cv::Mat& mat, const cv::Rect &rect, int cellSz);
+void blendImageRef(cv::Mat& mat,
+                   const cv::Point& org,
+                   const cv::Mat& img,
+                   const cv::Mat& alpha);
+
+#define GAPI_RENDER_TEST_FIXTURE_NV12(Fixture, API, Number, ...)  \
+struct Fixture : public RenderNV12TestBase API {                  \
+    __WRAP_VAARGS(DEFINE_SPECIFIC_PARAMS_##Number(__VA_ARGS__))   \
+    Fixture() {                                                   \
+        Init(sz_);                                                \
+    };                                                            \
+};
+
+#define GAPI_RENDER_TEST_FIXTURE_BGR(Fixture, API, Number, ...)  \
+struct Fixture : public RenderBGRTestBase API {                  \
+    __WRAP_VAARGS(DEFINE_SPECIFIC_PARAMS_##Number(__VA_ARGS__))   \
+    Fixture() {                                                   \
+        Init(sz_);                                                \
+    };                                                            \
 };
 
+#define GET_VA_ARGS(...) __VA_ARGS__
+#define GAPI_RENDER_TEST_FIXTURES(Fixture, API, Number, ...)                    \
+    GAPI_RENDER_TEST_FIXTURE_BGR(RenderBGR##Fixture,   GET_VA_ARGS(API), Number, __VA_ARGS__) \
+    GAPI_RENDER_TEST_FIXTURE_NV12(RenderNV12##Fixture, GET_VA_ARGS(API), Number, __VA_ARGS__) \
+
+using Points = std::vector<cv::Point>;
 } // opencv_test
 
 #endif //OPENCV_GAPI_RENDER_TESTS_HPP
diff --git a/modules/gapi/test/common/gapi_render_tests_inl.hpp b/modules/gapi/test/common/gapi_render_tests_inl.hpp
deleted file mode 100644
index fa0a1976a4..0000000000
--- a/modules/gapi/test/common/gapi_render_tests_inl.hpp
+++ /dev/null
@@ -1,44 +0,0 @@
-// This file is part of OpenCV project.
-// It is subject to the license terms in the LICENSE file found in the top-level directory
-// of this distribution and at http://opencv.org/license.html.
-//
-// Copyright (C) 2018-2019 Intel Corporation
-
-
-#ifndef OPENCV_GAPI_RENDER_TESTS_INL_HPP
-#define OPENCV_GAPI_RENDER_TESTS_INL_HPP
-
-#include <opencv2/gapi/render/render.hpp>
-#include "gapi_render_tests.hpp"
-
-namespace opencv_test
-{
-
-TEST_P(RenderNV12, AccuracyTest)
-{
-    std::tie(sz, prims) = GetParam();
-    Init();
-
-    cv::gapi::wip::draw::BGR2NV12(mat_gapi, y_mat_gapi, uv_mat_gapi);
-    cv::gapi::wip::draw::render(y_mat_gapi, uv_mat_gapi, prims);
-
-    ComputeRef();
-
-    EXPECT_EQ(0, cv::norm(y_mat_gapi, y_mat_ocv));
-    EXPECT_EQ(0, cv::norm(uv_mat_gapi, uv_mat_ocv));
-}
-
-TEST_P(RenderBGR, AccuracyTest)
-{
-    std::tie(sz, prims) = GetParam();
-    Init();
-
-    cv::gapi::wip::draw::render(mat_gapi, prims);
-    ComputeRef();
-
-    EXPECT_EQ(0, cv::norm(mat_gapi, mat_ocv));
-}
-
-} // opencv_test
-
-#endif //OPENCV_GAPI_RENDER_TESTS_INL_HPP
diff --git a/modules/gapi/test/common/gapi_tests_helpers.hpp b/modules/gapi/test/common/gapi_tests_helpers.hpp
index db1083df0c..ce0c90442d 100644
--- a/modules/gapi/test/common/gapi_tests_helpers.hpp
+++ b/modules/gapi/test/common/gapi_tests_helpers.hpp
@@ -42,6 +42,14 @@ namespace opencv_test
     __TUPLE_PARAM_TYPE(index) param_name = getSpecificParam<index>(); \
     __WRAP_VAARGS(__DEFINE_PARAMS_IMPL5(index+1, __VA_ARGS__))
 
+#define __DEFINE_PARAMS_IMPL7(index, param_name, ...) \
+    __TUPLE_PARAM_TYPE(index) param_name = getSpecificParam<index>(); \
+    __WRAP_VAARGS(__DEFINE_PARAMS_IMPL6(index+1, __VA_ARGS__))
+
+#define __DEFINE_PARAMS_IMPL8(index, param_name, ...) \
+    __TUPLE_PARAM_TYPE(index) param_name = getSpecificParam<index>(); \
+    __WRAP_VAARGS(__DEFINE_PARAMS_IMPL7(index+1, __VA_ARGS__))
+
 // user interface to define member variables of specified names
 #define DEFINE_SPECIFIC_PARAMS_0()
 
@@ -62,6 +70,12 @@ namespace opencv_test
 
 #define DEFINE_SPECIFIC_PARAMS_6(...) \
     __WRAP_VAARGS(__DEFINE_PARAMS_IMPL6(0, __VA_ARGS__))
+
+#define DEFINE_SPECIFIC_PARAMS_7(...) \
+    __WRAP_VAARGS(__DEFINE_PARAMS_IMPL7(0, __VA_ARGS__))
+
+#define DEFINE_SPECIFIC_PARAMS_8(...) \
+    __WRAP_VAARGS(__DEFINE_PARAMS_IMPL8(0, __VA_ARGS__))
 } // namespace opencv_test
 
 #endif //OPENCV_GAPI_TESTS_HELPERS_HPP
diff --git a/modules/gapi/test/cpu/gapi_render_tests_cpu.cpp b/modules/gapi/test/cpu/gapi_render_tests_cpu.cpp
deleted file mode 100644
index 80212e6c4b..0000000000
--- a/modules/gapi/test/cpu/gapi_render_tests_cpu.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-// This file is part of OpenCV project.
-// It is subject to the license terms in the LICENSE file found in the top-level directory
-// of this distribution and at http://opencv.org/license.html.
-//
-// Copyright (C) 2018 Intel Corporation
-
-
-#include "../test_precomp.hpp"
-#include "../common/gapi_render_tests.hpp"
-
-namespace opencv_test
-{
-
-/* NV12 test cases */
-INSTANTIATE_TEST_CASE_P(RenderNV12OCVRects, RenderNV12,
-                        Combine(Values(cv::Size(1280, 720),
-                                       cv::Size(640, 480)),
-                                Values(rects)));
-
-INSTANTIATE_TEST_CASE_P(RenderNV12OCVCircles, RenderNV12,
-                        Combine(Values(cv::Size(1280, 720),
-                                       cv::Size(640, 480)),
-                                Values(circles)));
-
-INSTANTIATE_TEST_CASE_P(RenderNV12OCVLines, RenderNV12,
-                        Combine(Values(cv::Size(1280, 720),
-                                       cv::Size(640, 480)),
-                                Values(lines)));
-
-INSTANTIATE_TEST_CASE_P(RenderNV12OCVMosaics, RenderNV12,
-                        Combine(Values(cv::Size(1280, 720),
-                                       cv::Size(640, 480)),
-                                Values(mosaics)));
-
-// FIXME difference in color
-INSTANTIATE_TEST_CASE_P(RenderNV12OCVImages, RenderNV12,
-                        Combine(Values(cv::Size(1280, 720),
-                                       cv::Size(640, 480)),
-                                Values(images)));
-
-INSTANTIATE_TEST_CASE_P(RenderNV12OCVPolygons, RenderNV12,
-                        Combine(Values(cv::Size(1280, 720),
-                                       cv::Size(640, 480)),
-                                Values(polygons)));
-
-INSTANTIATE_TEST_CASE_P(RenderNV12OCVTexts, RenderNV12,
-                        Combine(Values(cv::Size(1280, 720),
-                                       cv::Size(640, 480)),
-                                Values(texts)));
-
-/* BGR test cases */
-INSTANTIATE_TEST_CASE_P(RenderBGROCVRects, RenderBGR,
-                        Combine(Values(cv::Size(1280, 720),
-                                       cv::Size(640, 480)),
-                                Values(rects)));
-
-INSTANTIATE_TEST_CASE_P(RenderBGROCVCircles, RenderBGR,
-                        Combine(Values(cv::Size(1280, 720),
-                                       cv::Size(640, 480)),
-                                Values(circles)));
-
-INSTANTIATE_TEST_CASE_P(RenderBGROCVLines, RenderBGR,
-                        Combine(Values(cv::Size(1280, 720),
-                                       cv::Size(640, 480)),
-                                Values(lines)));
-
-INSTANTIATE_TEST_CASE_P(RenderBGROCVMosaics, RenderBGR,
-                        Combine(Values(cv::Size(1280, 720),
-                                       cv::Size(640, 480)),
-                                Values(mosaics)));
-
-INSTANTIATE_TEST_CASE_P(RenderBGROCVImages, RenderBGR,
-                        Combine(Values(cv::Size(1280, 720),
-                                       cv::Size(640, 480)),
-                                Values(images)));
-
-INSTANTIATE_TEST_CASE_P(RenderBGROCVPolygons, RenderBGR,
-                        Combine(Values(cv::Size(1280, 720),
-                                       cv::Size(640, 480)),
-                                Values(polygons)));
-
-INSTANTIATE_TEST_CASE_P(RenderBGROCVTexts, RenderBGR,
-                        Combine(Values(cv::Size(1280, 720),
-                                       cv::Size(640, 480)),
-                                Values(texts)));
-}
diff --git a/modules/gapi/test/render/gapi_render_tests_ocv.cpp b/modules/gapi/test/render/gapi_render_tests_ocv.cpp
new file mode 100644
index 0000000000..1ea3da14fd
--- /dev/null
+++ b/modules/gapi/test/render/gapi_render_tests_ocv.cpp
@@ -0,0 +1,460 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+//
+// Copyright (C) 2018 Intel Corporation
+
+
+#include "../test_precomp.hpp"
+#include "../common/gapi_render_tests.hpp"
+
+#include "api/render_priv.hpp"
+
+namespace opencv_test
+{
+
+GAPI_RENDER_TEST_FIXTURES(OCVTestTexts,     FIXTURE_API(std::string, cv::Point, int, double, cv::Scalar, int, int, bool), 8, text, org, ff, fs, color, thick, lt, blo)
+GAPI_RENDER_TEST_FIXTURES(OCVTestRects,     FIXTURE_API(cv::Rect, cv::Scalar, int, int, int),                             5, rect, color, thick, lt, shift)
+GAPI_RENDER_TEST_FIXTURES(OCVTestCircles,   FIXTURE_API(cv::Point, int, cv::Scalar, int, int, int),                       6, center, radius, color, thick, lt, shift)
+GAPI_RENDER_TEST_FIXTURES(OCVTestLines,     FIXTURE_API(cv::Point, cv::Point, cv::Scalar, int, int, int),                 6, pt1, pt2, color, thick, lt, shift)
+GAPI_RENDER_TEST_FIXTURES(OCVTestMosaics,   FIXTURE_API(cv::Rect, int, int),                                              3, mos, cellsz, decim)
+GAPI_RENDER_TEST_FIXTURES(OCVTestImages,    FIXTURE_API(cv::Rect, cv::Scalar, double),                                    3, rect, color, transparency)
+GAPI_RENDER_TEST_FIXTURES(OCVTestPolylines, FIXTURE_API(Points, cv::Scalar, int, int, int),                               5, points, color, thick, lt, shift)
+
+TEST_P(RenderBGROCVTestTexts, AccuracyTest)
+{
+    // G-API code //////////////////////////////////////////////////////////////
+    cv::gapi::wip::draw::Prims prims;
+    prims.emplace_back(cv::gapi::wip::draw::Text{text, org, ff, fs, color, thick, lt, blo});
+    cv::gapi::wip::draw::render(gapi_mat, prims);
+
+    // OpenCV code //////////////////////////////////////////////////////////////
+    {
+        cv::putText(ref_mat, text, org, ff, fs, color, thick, lt, blo);
+    }
+
+    // Comparison //////////////////////////////////////////////////////////////
+    {
+        EXPECT_EQ(0, cv::norm(gapi_mat, ref_mat));
+    }
+}
+
+TEST_P(RenderNV12OCVTestTexts, AccuracyTest)
+{
+    // G-API code //////////////////////////////////////////////////////////////
+    cv::gapi::wip::draw::Prims prims;
+    prims.emplace_back(cv::gapi::wip::draw::Text{text, org, ff, fs, color, thick, lt, blo});
+    cv::gapi::wip::draw::render(y_gapi_mat, uv_gapi_mat, prims);
+
+    // OpenCV code //////////////////////////////////////////////////////////////
+    {
+        // NV12 -> YUV
+        cv::Mat yuv;
+        cv::gapi::wip::draw::cvtNV12ToYUV(y_ref_mat, uv_ref_mat, yuv);
+
+        cv::putText(yuv, text, org, ff, fs, cvtBGRToYUVC(color), thick, lt, blo);
+
+        // YUV -> NV12
+        cv::gapi::wip::draw::cvtYUVToNV12(yuv, y_ref_mat, uv_ref_mat);
+    }
+
+    // Comparison //////////////////////////////////////////////////////////////
+    {
+        EXPECT_EQ(0, cv::norm(y_gapi_mat,  y_ref_mat));
+        EXPECT_EQ(0, cv::norm(uv_gapi_mat, uv_ref_mat));
+    }
+}
+
+TEST_P(RenderBGROCVTestRects, AccuracyTest)
+{
+    // G-API code //////////////////////////////////////////////////////////////
+    cv::gapi::wip::draw::Prims prims;
+    prims.emplace_back(cv::gapi::wip::draw::Rect{rect, color, thick, lt, shift});
+    cv::gapi::wip::draw::render(gapi_mat, prims);
+
+    // OpenCV code //////////////////////////////////////////////////////////////
+    {
+        cv::rectangle(ref_mat, rect, color, thick, lt, shift);
+    }
+
+    // Comparison //////////////////////////////////////////////////////////////
+    {
+        EXPECT_EQ(0, cv::norm(gapi_mat, ref_mat));
+    }
+}
+
+TEST_P(RenderNV12OCVTestRects, AccuracyTest)
+{
+    // G-API code //////////////////////////////////////////////////////////////
+    cv::gapi::wip::draw::Prims prims;
+    prims.emplace_back(cv::gapi::wip::draw::Rect{rect, color, thick, lt, shift});
+    cv::gapi::wip::draw::render(y_gapi_mat, uv_gapi_mat, prims);
+
+    // OpenCV code //////////////////////////////////////////////////////////////
+    {
+        // NV12 -> YUV
+        cv::Mat yuv;
+        cv::gapi::wip::draw::cvtNV12ToYUV(y_ref_mat, uv_ref_mat, yuv);
+
+        cv::rectangle(yuv, rect, cvtBGRToYUVC(color), thick, lt, shift);
+
+        // YUV -> NV12
+        cv::gapi::wip::draw::cvtYUVToNV12(yuv, y_ref_mat, uv_ref_mat);
+    }
+
+    // Comparison //////////////////////////////////////////////////////////////
+    {
+        EXPECT_EQ(0, cv::norm(y_gapi_mat,  y_ref_mat));
+        EXPECT_EQ(0, cv::norm(uv_gapi_mat, uv_ref_mat));
+    }
+}
+
+TEST_P(RenderBGROCVTestCircles, AccuracyTest)
+{
+    // G-API code //////////////////////////////////////////////////////////////
+    cv::gapi::wip::draw::Prims prims;
+    prims.emplace_back(cv::gapi::wip::draw::Circle{center, radius, color, thick, lt, shift});
+    cv::gapi::wip::draw::render(gapi_mat, prims);
+
+    // OpenCV code //////////////////////////////////////////////////////////////
+    {
+        cv::circle(ref_mat, center, radius, color, thick, lt, shift);
+    }
+
+    // Comparison //////////////////////////////////////////////////////////////
+    {
+        EXPECT_EQ(0, cv::norm(gapi_mat, ref_mat));
+    }
+}
+
+TEST_P(RenderNV12OCVTestCircles, AccuracyTest)
+{
+    // G-API code //////////////////////////////////////////////////////////////
+    cv::gapi::wip::draw::Prims prims;
+    prims.emplace_back(cv::gapi::wip::draw::Circle{center, radius, color, thick, lt, shift});
+    cv::gapi::wip::draw::render(y_gapi_mat, uv_gapi_mat, prims);
+
+    // OpenCV code //////////////////////////////////////////////////////////////
+    {
+        // NV12 -> YUV
+        cv::Mat yuv;
+        cv::gapi::wip::draw::cvtNV12ToYUV(y_ref_mat, uv_ref_mat, yuv);
+
+        cv::circle(yuv, center, radius, cvtBGRToYUVC(color), thick, lt, shift);
+
+        // YUV -> NV12
+        cv::gapi::wip::draw::cvtYUVToNV12(yuv, y_ref_mat, uv_ref_mat);
+    }
+
+    // Comparison //////////////////////////////////////////////////////////////
+    {
+        EXPECT_EQ(0, cv::norm(y_gapi_mat,  y_ref_mat));
+        EXPECT_EQ(0, cv::norm(uv_gapi_mat, uv_ref_mat));
+    }
+}
+
+TEST_P(RenderBGROCVTestLines, AccuracyTest)
+{
+    // G-API code //////////////////////////////////////////////////////////////
+    cv::gapi::wip::draw::Prims prims;
+    prims.emplace_back(cv::gapi::wip::draw::Line{pt1, pt2, color, thick, lt, shift});
+    cv::gapi::wip::draw::render(gapi_mat, prims);
+
+    // OpenCV code //////////////////////////////////////////////////////////////
+    {
+        cv::line(ref_mat, pt1, pt2, color, thick, lt, shift);
+    }
+
+    // Comparison //////////////////////////////////////////////////////////////
+    {
+        EXPECT_EQ(0, cv::norm(gapi_mat, ref_mat));
+    }
+}
+
+TEST_P(RenderNV12OCVTestLines, AccuracyTest)
+{
+    // G-API code //////////////////////////////////////////////////////////////
+    cv::gapi::wip::draw::Prims prims;
+    prims.emplace_back(cv::gapi::wip::draw::Line{pt1, pt2, color, thick, lt, shift});
+    cv::gapi::wip::draw::render(y_gapi_mat, uv_gapi_mat, prims);
+
+    // OpenCV code //////////////////////////////////////////////////////////////
+    {
+        // NV12 -> YUV
+        cv::Mat yuv;
+        cv::gapi::wip::draw::cvtNV12ToYUV(y_ref_mat, uv_ref_mat, yuv);
+
+        cv::line(yuv, pt1, pt2, cvtBGRToYUVC(color), thick, lt, shift);
+
+        // YUV -> NV12
+        cv::gapi::wip::draw::cvtYUVToNV12(yuv, y_ref_mat, uv_ref_mat);
+    }
+
+    // Comparison //////////////////////////////////////////////////////////////
+    {
+        EXPECT_EQ(0, cv::norm(y_gapi_mat,  y_ref_mat));
+        EXPECT_EQ(0, cv::norm(uv_gapi_mat, uv_ref_mat));
+    }
+}
+
+TEST_P(RenderBGROCVTestMosaics, AccuracyTest)
+{
+    // G-API code //////////////////////////////////////////////////////////////
+    cv::gapi::wip::draw::Prims prims;
+    prims.emplace_back(cv::gapi::wip::draw::Mosaic{mos, cellsz, decim});
+    cv::gapi::wip::draw::render(gapi_mat, prims);
+
+    // OpenCV code //////////////////////////////////////////////////////////////
+    {
+        drawMosaicRef(ref_mat, mos, cellsz);
+    }
+
+    // Comparison //////////////////////////////////////////////////////////////
+    {
+        EXPECT_EQ(0, cv::norm(gapi_mat, ref_mat));
+    }
+}
+
+TEST_P(RenderNV12OCVTestMosaics, AccuracyTest)
+{
+    // G-API code //////////////////////////////////////////////////////////////
+    cv::gapi::wip::draw::Prims prims;
+    prims.emplace_back(cv::gapi::wip::draw::Mosaic{mos, cellsz, decim});
+    cv::gapi::wip::draw::render(y_gapi_mat, uv_gapi_mat, prims);
+
+    // OpenCV code //////////////////////////////////////////////////////////////
+    {
+        // NV12 -> YUV
+        cv::Mat yuv;
+        cv::gapi::wip::draw::cvtNV12ToYUV(y_ref_mat, uv_ref_mat, yuv);
+
+        drawMosaicRef(yuv, mos, cellsz);
+
+        // YUV -> NV12
+        cv::gapi::wip::draw::cvtYUVToNV12(yuv, y_ref_mat, uv_ref_mat);
+    }
+
+    // Comparison //////////////////////////////////////////////////////////////
+    {
+        EXPECT_EQ(0, cv::norm(y_gapi_mat,  y_ref_mat));
+        EXPECT_EQ(0, cv::norm(uv_gapi_mat, uv_ref_mat));
+    }
+}
+
+TEST_P(RenderBGROCVTestImages, AccuracyTest)
+{
+    cv::Mat img(rect.size(), CV_8UC3, color);
+    cv::Mat alpha(rect.size(), CV_32FC1, transparency);
+    auto tl = rect.tl();
+    cv::Point org = {tl.x, tl.y + rect.size().height};
+
+    // G-API code //////////////////////////////////////////////////////////////
+    cv::gapi::wip::draw::Prims prims;
+    prims.emplace_back(cv::gapi::wip::draw::Image{org, img, alpha});
+    cv::gapi::wip::draw::render(gapi_mat, prims);
+
+    // OpenCV code //////////////////////////////////////////////////////////////
+    {
+        blendImageRef(ref_mat, org, img, alpha);
+    }
+
+    // Comparison //////////////////////////////////////////////////////////////
+    {
+        EXPECT_EQ(0, cv::norm(gapi_mat, ref_mat));
+    }
+}
+
+TEST_P(RenderNV12OCVTestImages, AccuracyTest)
+{
+    cv::Mat img(rect.size(), CV_8UC3, color);
+    cv::Mat alpha(rect.size(), CV_32FC1, transparency);
+    auto tl = rect.tl();
+    cv::Point org = {tl.x, tl.y + rect.size().height};
+
+    // G-API code //////////////////////////////////////////////////////////////
+    cv::gapi::wip::draw::Prims prims;
+    prims.emplace_back(cv::gapi::wip::draw::Image{org, img, alpha});
+    cv::gapi::wip::draw::render(y_gapi_mat, uv_gapi_mat, prims);
+
+    // OpenCV code //////////////////////////////////////////////////////////////
+    {
+        // NV12 -> YUV
+        cv::Mat yuv;
+        cv::gapi::wip::draw::cvtNV12ToYUV(y_ref_mat, uv_ref_mat, yuv);
+
+        cv::Mat yuv_img;
+        cv::cvtColor(img, yuv_img, cv::COLOR_BGR2YUV);
+        blendImageRef(yuv, org, yuv_img, alpha);
+
+        // YUV -> NV12
+        cv::gapi::wip::draw::cvtYUVToNV12(yuv, y_ref_mat, uv_ref_mat);
+    }
+
+    // Comparison //////////////////////////////////////////////////////////////
+    {
+        EXPECT_EQ(0, cv::norm(y_gapi_mat,  y_ref_mat));
+        EXPECT_EQ(0, cv::norm(uv_gapi_mat, uv_ref_mat));
+    }
+}
+
+TEST_P(RenderBGROCVTestPolylines, AccuracyTest)
+{
+    // G-API code //////////////////////////////////////////////////////////////
+    cv::gapi::wip::draw::Prims prims;
+    prims.emplace_back(cv::gapi::wip::draw::Poly{points, color, thick, lt, shift});
+    cv::gapi::wip::draw::render(gapi_mat, prims);
+
+    // OpenCV code //////////////////////////////////////////////////////////////
+    {
+        std::vector<std::vector<cv::Point>> array_points{points};
+        cv::fillPoly(ref_mat, array_points, color, lt, shift);
+    }
+
+    // Comparison //////////////////////////////////////////////////////////////
+    {
+        EXPECT_EQ(0, cv::norm(gapi_mat, ref_mat));
+    }
+}
+
+TEST_P(RenderNV12OCVTestPolylines, AccuracyTest)
+{
+    // G-API code //////////////////////////////////////////////////////////////
+    cv::gapi::wip::draw::Prims prims;
+    prims.emplace_back(cv::gapi::wip::draw::Poly{points, color, thick, lt, shift});
+    cv::gapi::wip::draw::render(y_gapi_mat, uv_gapi_mat, prims);
+
+    // OpenCV code //////////////////////////////////////////////////////////////
+    {
+        // NV12 -> YUV
+        cv::Mat yuv;
+        cv::gapi::wip::draw::cvtNV12ToYUV(y_ref_mat, uv_ref_mat, yuv);
+
+        std::vector<std::vector<cv::Point>> pp{points};
+        cv::fillPoly(yuv, pp, cvtBGRToYUVC(color), lt, shift);
+
+        // YUV -> NV12
+        cv::gapi::wip::draw::cvtYUVToNV12(yuv, y_ref_mat, uv_ref_mat);
+    }
+
+    // Comparison //////////////////////////////////////////////////////////////
+    {
+        EXPECT_EQ(0, cv::norm(y_gapi_mat,  y_ref_mat));
+        EXPECT_EQ(0, cv::norm(uv_gapi_mat, uv_ref_mat));
+    }
+}
+
+// FIXME avoid code duplicate for NV12 and BGR cases
+INSTANTIATE_TEST_CASE_P(RenderBGROCVTestRectsImpl, RenderBGROCVTestRects,
+                        Combine(Values(cv::Size(1280, 720)),
+                                Values(cv::Rect(100, 100, 200, 200)),
+                                Values(cv::Scalar(100, 50, 150)),
+                                Values(2),
+                                Values(LINE_8),
+                                Values(0)));
+
+INSTANTIATE_TEST_CASE_P(RenderNV12OCVTestRectsImpl, RenderNV12OCVTestRects,
+                        Combine(Values(cv::Size(1280, 720)),
+                                       Values(cv::Rect(100, 100, 200, 200)),
+                                       Values(cv::Scalar(100, 50, 150)),
+                                       Values(2),
+                                       Values(LINE_8),
+                                       Values(0)));
+
+INSTANTIATE_TEST_CASE_P(RenderBGROCVTestCirclesImpl, RenderBGROCVTestCircles,
+                        Combine(Values(cv::Size(1280, 720)),
+                                Values(cv::Point(100, 100)),
+                                Values(10),
+                                Values(cv::Scalar(100, 50, 150)),
+                                Values(2),
+                                Values(LINE_8),
+                                Values(0)));
+
+INSTANTIATE_TEST_CASE_P(RenderNV12OCVTestCirclesImpl, RenderNV12OCVTestCircles,
+                        Combine(Values(cv::Size(1280, 720)),
+                                Values(cv::Point(100, 100)),
+                                Values(10),
+                                Values(cv::Scalar(100, 50, 150)),
+                                Values(2),
+                                Values(LINE_8),
+                                Values(0)));
+
+INSTANTIATE_TEST_CASE_P(RenderBGROCVTestLinesImpl, RenderBGROCVTestLines,
+                        Combine(Values(cv::Size(1280, 720)),
+                                Values(cv::Point(100, 100)),
+                                Values(cv::Point(200, 200)),
+                                Values(cv::Scalar(100, 50, 150)),
+                                Values(2),
+                                Values(LINE_8),
+                                Values(0)));
+
+INSTANTIATE_TEST_CASE_P(RenderNV12OCVTestLinesImpl, RenderNV12OCVTestLines,
+                        Combine(Values(cv::Size(1280, 720)),
+                                Values(cv::Point(100, 100)),
+                                Values(cv::Point(200, 200)),
+                                Values(cv::Scalar(100, 50, 150)),
+                                Values(2),
+                                Values(LINE_8),
+                                Values(0)));
+
+INSTANTIATE_TEST_CASE_P(RenderBGROCVTestTextsImpl, RenderBGROCVTestTexts,
+                        Combine(Values(cv::Size(1280, 720)),
+                                Values("SomeText"),
+                                Values(cv::Point(200, 200)),
+                                Values(FONT_HERSHEY_SIMPLEX),
+                                Values(2.0),
+                                Values(cv::Scalar(0, 255, 0)),
+                                Values(2),
+                                Values(LINE_8),
+                                Values(false)));
+
+INSTANTIATE_TEST_CASE_P(RenderNV12OCVTestTextsImpl, RenderNV12OCVTestTexts,
+                        Combine(Values(cv::Size(1280, 720)),
+                                Values("SomeText"),
+                                Values(cv::Point(200, 200)),
+                                Values(FONT_HERSHEY_SIMPLEX),
+                                Values(2.0),
+                                Values(cv::Scalar(0, 255, 0)),
+                                Values(2),
+                                Values(LINE_8),
+                                Values(false)));
+
+INSTANTIATE_TEST_CASE_P(RenderBGROCVTestMosaicsImpl, RenderBGROCVTestMosaics,
+                        Combine(Values(cv::Size(1280, 720)),
+                                Values(cv::Rect(100, 100, 200, 200)),
+                                Values(25),
+                                Values(0)));
+
+INSTANTIATE_TEST_CASE_P(RenderNV12OCVTestMosaicsImpl, RenderNV12OCVTestMosaics,
+                        Combine(Values(cv::Size(1280, 720)),
+                                Values(cv::Rect(100, 100, 200, 200)),
+                                Values(25),
+                                Values(0)));
+
+INSTANTIATE_TEST_CASE_P(RenderBGROCVTestImagesImpl, RenderBGROCVTestImages,
+                        Combine(Values(cv::Size(1280, 720)),
+                                Values(cv::Rect(100, 100, 200, 200)),
+                                Values(cv::Scalar(100, 150, 60)),
+                                Values(1.0)));
+
+INSTANTIATE_TEST_CASE_P(RenderNV12OCVTestImagesImpl, RenderNV12OCVTestImages,
+                        Combine(Values(cv::Size(1280, 720)),
+                                Values(cv::Rect(100, 100, 200, 200)),
+                                Values(cv::Scalar(100, 150, 60)),
+                                Values(1.0)));
+
+INSTANTIATE_TEST_CASE_P(RenderBGROCVTestPolylinesImpl, RenderBGROCVTestPolylines,
+                        Combine(Values(cv::Size(1280, 720)),
+                                Values(std::vector<cv::Point>{{100, 100}, {200, 200}, {150, 300}, {400, 150}}),
+                                Values(cv::Scalar(100, 150, 60)),
+                                Values(2),
+                                Values(LINE_8),
+                                Values(0)));
+
+INSTANTIATE_TEST_CASE_P(RenderNV12OCVTestPolylinesImpl, RenderNV12OCVTestPolylines,
+                        Combine(Values(cv::Size(1280, 720)),
+                                Values(std::vector<cv::Point>{{100, 100}, {200, 200}, {150, 300}, {400, 150}}),
+                                Values(cv::Scalar(100, 150, 60)),
+                                Values(2),
+                                Values(LINE_8),
+                                Values(0)));
+}