[meta-freescale] [PATCH v2 03/14] imx-gpu-apitrace: Move apitrace out of imx-gpu-viv v6

Tom Hochstein tom.hochstein at nxp.com
Wed Nov 15 13:02:12 PST 2017


Signed-off-by: Tom Hochstein <tom.hochstein at nxp.com>
---
 .../0001-add-docs-HOWTO.markdown.patch             |  61 +++
 ...cs-Freescale_apitrace_user_guide.markdown.patch |  91 ++++
 ...0003-add-docs-Freescale_apitrace.markdown.patch | 133 ++++++
 .../0004-add-docs-apitrace_test.markdown.patch     | 144 ++++++
 .../0005-add-apitrace_dalvik.sh.patch              |  75 +++
 .../0006-add-test_android.sh.patch                 |  72 +++
 .../imx-gpu-apitrace/0007-add-test_yocto.sh.patch  | 131 ++++++
 .../0008-docs-mention-apitrace_dalvik.sh.patch     |  28 ++
 .../0009-add-retrace-glws_nonx.cpp.patch           | 515 +++++++++++++++++++++
 .../0010-cmake-use-glws_nonx-for-Vivante.patch     |  62 +++
 .../0011-cli_trace-export-ENABLE_API_TRACE-1.patch |  37 ++
 .../0012-use-dlsym-to-get-function-pointers.patch  |  31 ++
 ...ver-does-not-support-GL_RGB-in-openGL-dri.patch |  36 ++
 ...-hangs-when-retracing-OGLESParticles-on-m.patch |  28 ++
 ...5-egl-define-egl-native-types-for-non-x11.patch |  36 ++
 ...-don-t-recreate-the-EGL-surface-on-resize.patch |  32 ++
 .../imx-gpu-apitrace/0017-add-Image-getMD5.patch   |  69 +++
 ...ace-use-Image-getMD5-for-image-comparison.patch | 175 +++++++
 ...race-don-t-use-dlsym-on-aliased-functions.patch |  91 ++++
 .../0020-egl-glx-trace-add-ApiTraceEnabled.patch   |  79 ++++
 .../0021-LocalWriter-make-a-writer-ignorable.patch | 101 ++++
 ...-retrace-tutorial3-is-different-with-trac.patch |  82 ++++
 .../0023-add-support-for-Vivante-extensions.patch  | 444 ++++++++++++++++++
 ...70-ccc-cannot-trace-mesa-demos-vertexrate.patch |  34 ++
 ...025-MGS-1271-ccc-disable-X-debug-function.patch |  30 ++
 ...-MGS-1721-ccc-fix-broken-build-on-AArch64.patch |  43 ++
 ...c-blank-screen-when-retracing-es20-sdk-ap.patch |  58 +++
 ...c-add-the-TOT-commit-SHA1-inside-the-bina.patch |  55 +++
 ...-avoid-memcpy-in-glTexDirectInvalidateVIV.patch | 283 +++++++++++
 ...-retrace-support-eglCreatePixmapSurface-o.patch |  98 ++++
 ...acktrace-define-HAVE_STDINT_H-in-config.h.patch |  36 ++
 .../0032-changed-disable-X11-mechanism.patch       |  18 +
 ...c-Miss-usr-bin-eglretrace-file-in-FB-and-.patch |  70 +++
 .../0034-MGS-make-multiarch-optional.patch         |  22 +
 ...en-don-t-override-symbols-in-Vivante-libs.patch | 101 ++++
 .../imx-gpu-apitrace/imx-gpu-apitrace_7.1.0.bb     |  57 +++
 36 files changed, 3458 insertions(+)
 create mode 100644 recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0001-add-docs-HOWTO.markdown.patch
 create mode 100644 recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0002-add-docs-Freescale_apitrace_user_guide.markdown.patch
 create mode 100644 recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0003-add-docs-Freescale_apitrace.markdown.patch
 create mode 100644 recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0004-add-docs-apitrace_test.markdown.patch
 create mode 100644 recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0005-add-apitrace_dalvik.sh.patch
 create mode 100644 recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0006-add-test_android.sh.patch
 create mode 100644 recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0007-add-test_yocto.sh.patch
 create mode 100644 recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0008-docs-mention-apitrace_dalvik.sh.patch
 create mode 100644 recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0009-add-retrace-glws_nonx.cpp.patch
 create mode 100644 recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0010-cmake-use-glws_nonx-for-Vivante.patch
 create mode 100644 recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0011-cli_trace-export-ENABLE_API_TRACE-1.patch
 create mode 100644 recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0012-use-dlsym-to-get-function-pointers.patch
 create mode 100644 recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0013-Vivante-driver-does-not-support-GL_RGB-in-openGL-dri.patch
 create mode 100644 recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0014-MGS-469-GPU-hangs-when-retracing-OGLESParticles-on-m.patch
 create mode 100644 recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0015-egl-define-egl-native-types-for-non-x11.patch
 create mode 100644 recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0016-don-t-recreate-the-EGL-surface-on-resize.patch
 create mode 100644 recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0017-add-Image-getMD5.patch
 create mode 100644 recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0018-retrace-use-Image-getMD5-for-image-comparison.patch
 create mode 100644 recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0019-egltrace-don-t-use-dlsym-on-aliased-functions.patch
 create mode 100644 recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0020-egl-glx-trace-add-ApiTraceEnabled.patch
 create mode 100644 recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0021-LocalWriter-make-a-writer-ignorable.patch
 create mode 100644 recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0022-MGS-309-ccc-retrace-tutorial3-is-different-with-trac.patch
 create mode 100644 recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0023-add-support-for-Vivante-extensions.patch
 create mode 100644 recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0024-MGS-470-ccc-cannot-trace-mesa-demos-vertexrate.patch
 create mode 100644 recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0025-MGS-1271-ccc-disable-X-debug-function.patch
 create mode 100644 recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0026-MGS-1721-ccc-fix-broken-build-on-AArch64.patch
 create mode 100644 recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0027-MGS-1859-ccc-blank-screen-when-retracing-es20-sdk-ap.patch
 create mode 100644 recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0028-MGS-2254-ccc-add-the-TOT-commit-SHA1-inside-the-bina.patch
 create mode 100644 recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0029-MGS-815-ccc-avoid-memcpy-in-glTexDirectInvalidateVIV.patch
 create mode 100644 recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0030-MGS-814-ccc-retrace-support-eglCreatePixmapSurface-o.patch
 create mode 100644 recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0031-libbacktrace-define-HAVE_STDINT_H-in-config.h.patch
 create mode 100644 recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0032-changed-disable-X11-mechanism.patch
 create mode 100644 recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0033-MGS-2963-ccc-Miss-usr-bin-eglretrace-file-in-FB-and-.patch
 create mode 100644 recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0034-MGS-make-multiarch-optional.patch
 create mode 100644 recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0035-dlopen-don-t-override-symbols-in-Vivante-libs.patch
 create mode 100644 recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace_7.1.0.bb

diff --git a/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0001-add-docs-HOWTO.markdown.patch b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0001-add-docs-HOWTO.markdown.patch
new file mode 100644
index 0000000..219fd7a
--- /dev/null
+++ b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0001-add-docs-HOWTO.markdown.patch
@@ -0,0 +1,61 @@
+From a3598a20937c9fd8ad85a8797186db5aeb4b0095 Mon Sep 17 00:00:00 2001
+From: Yuchou Gan <yuchou.gan at nxp.com>
+Date: Thu, 19 Jan 2017 09:38:20 +0200
+Subject: [PATCH 01/31] add docs/HOWTO.markdown
+
+---
+ docs/HOWTO.markdown | 42 ++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 42 insertions(+)
+ create mode 100644 docs/HOWTO.markdown
+
+diff --git a/docs/HOWTO.markdown b/docs/HOWTO.markdown
+new file mode 100644
+index 0000000..fed8fc2
+--- /dev/null
++++ b/docs/HOWTO.markdown
+@@ -0,0 +1,42 @@
++# Build for i.MX6 #
++## Yocto ##
++
++    export CROSSTOOLCHAIN=...
++    export CMAKE_SYSROOT=...
++    cmake -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain/arm-gnueabi.toolchain.cmake -f CMakeLists.txt -DCMAKE_INSTALL_PREFIX:PATH=<path>
++    make && make install
++
++
++## Android ##
++
++    cmake -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain/android.toolchain.cmake -f CMakeLists.txt -DCMAKE_INSTALL_PREFIX:PATH=<path> -DANDROID_NATIVE_API_LEVEL=android-19 -DANDROID_NDK=<ndk tool>
++
++KitKat uses sdk level 19; Lollipop uses 21:
++    make && make install
++
++
++# Build for x86 #
++
++    cmake -f CMakeLists.txt -DCMAKE_INSTALL_PREFIX:PATH=<path>
++    make && make install
++
++# Tips #
++## Switch cross build and native build ##
++
++    make clean
++    find . -name CMakeFiles -exec rm -rf "{}" \;
++    find . -name CMakeCache.txt -exec rm "{}" \;
++
++
++## To enable qapitrace ##
++
++You must install qt4 development packages:
++
++    sudo apt-get install qt4-default qt4-qmake qt4-dev-tools libqt4-dev libqt4-opengl-dev automoc
++
++
++## Fix empty AR in link.txt created by cmake ##
++
++For cross build, macro CMAKE_AR may not work. Use following command to replace the empty AR command with correct value:
++
++    find . -name "link.txt" -exec grep -l -e "\"\" cr" "{}" \; | xargs sed -i 's#\"\"#'$CROSSTOOLCHAIN'-ar#'
+-- 
+2.7.4
+
diff --git a/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0002-add-docs-Freescale_apitrace_user_guide.markdown.patch b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0002-add-docs-Freescale_apitrace_user_guide.markdown.patch
new file mode 100644
index 0000000..a70b59a
--- /dev/null
+++ b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0002-add-docs-Freescale_apitrace_user_guide.markdown.patch
@@ -0,0 +1,91 @@
+From 7f37ca44b70f3bbaa3210bf63c11d4f8bb74b42a Mon Sep 17 00:00:00 2001
+From: Adrian Negreanu <groleo at gmail.com>
+Date: Thu, 6 Apr 2017 09:37:26 +0300
+Subject: [PATCH 02/31] add docs/Freescale_apitrace_user_guide.markdown
+
+---
+ docs/Freescale_apitrace_user_guide.markdown | 72 +++++++++++++++++++++++++++++
+ 1 file changed, 72 insertions(+)
+ create mode 100644 docs/Freescale_apitrace_user_guide.markdown
+
+diff --git a/docs/Freescale_apitrace_user_guide.markdown b/docs/Freescale_apitrace_user_guide.markdown
+new file mode 100644
+index 0000000..cec66ce
+--- /dev/null
++++ b/docs/Freescale_apitrace_user_guide.markdown
+@@ -0,0 +1,72 @@
++# Freescale apitrace release note
++
++## Overview
++
++Freescale apitrace is a set of tools enhanced from open source project apitrace.
++Freescale version adds support to Freescale i.MX6 chipsets which use Vivante GPU IP.
++
++
++## Purpose
++
++This tool is to provide the gpu application and driver developers a way to look
++inside the application with source code. It also provides a way to port an
++application to another platform with source requirement. Comparing with
++Vivante’s similar tool vTracer/vPlayer, Freescale apitrace provides some new
++features:
++
++```
++Feature                     Vivante Apitrace   Comment
++---------------------------+-------+-------+-------------------------------------.
++Easy to use                | N     | Y     | Vivante’s tools have Too many       |
++                           |       |       | settings to remember, and user must |
++                           |       |       | make sure tool version matches gpu  |
++                           |       |       | driver version. There’s a strong    |
++                           |       |       | dependency between tool and gpu     |
++                           |       |       | driver.                             |
++---------------------------+-------+-------+-------------------------------------+
++License                    | N     | Y     | vPlayer/vTracer: closed source      |
++control                    |       |       | Apitrace: BSD                       |
++-------+-+-----------------+-------+-------+-------------------------------------+
++Trace  |O| Linux           | Y     | Y     |                                     |
++       |S| Android         | Y     | Y     |                                     |
++       |-+-----------------+-------+-------+-------------------------------------+
++       |A| OpenGL          | N     | Y     |                                     |
++       |P| GLES1           | Y     | Y     |                                     |
++       |I| GLES2           | Y     | Y     |                                     |
++       | | GLES3           | Y     | Y     | With my patch to support ES 3.0     |
++       | | OpenVG          | ???   | ???   |                                     |
++-------+-+-----------------+-------+-------+-------------------------------------+
++Replay |O| Linux           | Y     | Y     |                                     |
++       |S| Android         | Y     | ???   |                                     |
++       | | Windows         | Y     | Y     |                                     |
++       |-+-----------------+-------+-------+-------------------------------------+
++       |Frame dump         | Y     | Y     |                                     |
++       |Frame range&repeat | Y     | Y     |                                     |
++       |Insert error check | Y     | Y     |                                     |
++       |Insert glFinish    | Y     | N     |                                     |
++       |Dump per-call state| N     | Y     |                                     |
++-------+-------------------+-------+-------+-------------------------------------+
++Post   | View framebuffer  | N     | Y     |                                     |
++process| View textures     | N     | Y     |                                     |
++       | Editing           | N     | Y     |                                     |
++       | Performance Mon   | N     | Y     |                                     |
++       | Encode to video   | N     | Y     |                                     |
++-------+-------------------+-------+-------+-------------------------------------'
++```
++
++## Release History
++```
++Version  Date
++.-------+---------.
++| 0.1   | 2014/12 |
++'-------+---------'
++```
++
++
++## Known Issues
++
++```
++MGS-310 APITRACE: Will print "/usr/lib/libstdc++.so.6: _ZNSo5writeEPKci+0x4f" using udisk to store trace files
++MGS-309 APITRACE: retrace "tutorial3" is different with trace it
++MGS-308 APITRACE: Should support to create children dir
++```
+-- 
+2.7.4
+
diff --git a/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0003-add-docs-Freescale_apitrace.markdown.patch b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0003-add-docs-Freescale_apitrace.markdown.patch
new file mode 100644
index 0000000..4b456b7
--- /dev/null
+++ b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0003-add-docs-Freescale_apitrace.markdown.patch
@@ -0,0 +1,133 @@
+From 34dfb168829133af38577509017d7505ce53122f Mon Sep 17 00:00:00 2001
+From: Adrian Negreanu <groleo at gmail.com>
+Date: Wed, 5 Apr 2017 16:17:47 +0300
+Subject: [PATCH 03/31] add docs/Freescale_apitrace.markdown
+
+---
+ docs/Freescale_apitrace.markdown | 113 +++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 113 insertions(+)
+ create mode 100644 docs/Freescale_apitrace.markdown
+
+diff --git a/docs/Freescale_apitrace.markdown b/docs/Freescale_apitrace.markdown
+new file mode 100644
+index 0000000..fda3a2b
+--- /dev/null
++++ b/docs/Freescale_apitrace.markdown
+@@ -0,0 +1,113 @@
++# Freescale Apitrace
++
++## How apitrace works
++
++
++### trace
++
++Make use of LD_PRELOAD (for Linux) to preload wrapper library.
++Every OpenGL(ES) API call will be redirected to wrapper library.
++In the wrapper, current thread ID, API name, and associated data
++are recorded into a file.  The wrapper also overrides C
++function “dlopen” (for Linux) to monitor OpenGL libraries loading.
++
++
++### replay
++
++Also called _retrace_, it reads in trace file and run OpenGL(ES)
++APIs on host one by one. Each OpenGL(ES) API call will be processed by
++a callback function. In that callback, extra job can be inserted.
++
++
++### qapitrace
++
++A tool to analysis trace file, with GUI display.
++
++
++## Advantage of apitrace
++
++* More features provided by apitrace than vTracer/vPlayer as listed
++before. Some features are important (inspect gpu state at any call,
++edit API call, etc.) but missing from vTracer.
++
++* It is open source, so we can freely enhance the tool according to our
++requirement.
++
++* It is possible to add OpenVG API support. It will be
++a big advantage if OpenVG is supported.
++
++* ADIT requires *replay* to be run on their layer management system.
++vPlayer fails to provide such support.
++But apitrace has a good framework and is convenient for ADIT
++to hook in the window creation function (just create a derived class
++from class EglDrawable)
++
++* Extend the tool to use it as conformance or
++regression test tool Currently there’re lots of gpu applications. Test
++team has to watch the screen to judge whether rendering is ok or not. No
++objective tool to verify correctness of gpu rendering.  With this tool,
++we can develop a tool to compare frame by frame between a reference
++board and a debug board. This kind of tool can benefit test team (and
++customers) to deal with the heavier and heavier test tasks.
++
++* Quality is better Vivante’s tools often meet this or that problem. This open
++source tool is originated from Intel Corporation and other companies.
++
++
++## Difference with original apitrace
++
++Original apitrace won’t run
++with Vivante’s gpu software stack. Must use Freescale version
++instead. Freescale also enhanced apitrace to support OpenGL
++ES 3.0.
++
++
++## Differences between apitrace and vProfiler/vPlayer Vivante
++
++Provides vTracer and vPlayer to help debug OpenGL ES 1.1/2.0/3.0 API
++call. There’s another tool, apitrace, can be used to replace vTracer
++and vPlayer.Freescale apitrace.docx
++
++
++Here’s a table comparing main features provided by Vivante tools
++and apitrace:
++
++```
++Feature                     Vivante Apitrace   Comment
++---------------------------+-------+-------+-------------------------------------.
++Easy to use                | N     | Y     | Vivante’s tools have Too many       |
++                           |       |       | settings to remember, and user must |
++                           |       |       | make sure tool version matches gpu  |
++                           |       |       | driver version. There’s a strong    |
++                           |       |       | dependency between tool and gpu     |
++                           |       |       | driver.                             |
++---------------------------+-------+-------+-------------------------------------+
++License                    | N     | Y     | vPlayer/vTracer: closed source      |
++control                    |       |       | Apitrace: BSD                       |
++-------+-+-----------------+-------+-------+-------------------------------------+
++Trace  |O| Linux           | Y     | Y     |                                     |
++       |S| Android         | Y     | Y     |                                     |
++       |-+-----------------+-------+-------+-------------------------------------+
++       |A| OpenGL          | N     | Y     |                                     |
++       |P| GLES1           | Y     | Y     |                                     |
++       |I| GLES2           | Y     | Y     |                                     |
++       | | GLES3           | Y     | Y     | With my patch to support ES 3.0     |
++       | | OpenVG          | ???   | ???   |                                     |
++-------+-+-----------------+-------+-------+-------------------------------------+
++Replay |O| Linux           | Y     | Y     |                                     |
++       |S| Android         | Y     | ???   |                                     |
++       | | Windows         | Y     | Y     |                                     |
++       |-+-----------------+-------+-------+-------------------------------------+
++       |Frame dump         | Y     | Y     |                                     |
++       |Frame range&repeat | Y     | Y     |                                     |
++       |Insert error check | Y     | Y     |                                     |
++       |Insert glFinish    | Y     | N     |                                     |
++       |Dump per-call state| N     | Y     |                                     |
++-------+-------------------+-------+-------+-------------------------------------+
++Post   | View framebuffer  | N     | Y     |                                     |
++process| View textures     | N     | Y     |                                     |
++       | Editing           | N     | Y     |                                     |
++       | Performance Mon   | N     | Y     |                                     |
++       | Encode to video   | N     | Y     |                                     |
++-------+-------------------+-------+-------+-------------------------------------+
++```
+\ No newline at end of file
+-- 
+2.7.4
+
diff --git a/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0004-add-docs-apitrace_test.markdown.patch b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0004-add-docs-apitrace_test.markdown.patch
new file mode 100644
index 0000000..2cfefc8
--- /dev/null
+++ b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0004-add-docs-apitrace_test.markdown.patch
@@ -0,0 +1,144 @@
+From f78922b19fec8c8cd40bdf42b18c09fed0a7f597 Mon Sep 17 00:00:00 2001
+From: Adrian Negreanu <groleo at gmail.com>
+Date: Thu, 6 Apr 2017 10:10:40 +0300
+Subject: [PATCH 04/31] add docs/apitrace_test.markdown
+
+---
+ docs/apitrace_test.markdown | 125 ++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 125 insertions(+)
+ create mode 100644 docs/apitrace_test.markdown
+
+diff --git a/docs/apitrace_test.markdown b/docs/apitrace_test.markdown
+new file mode 100644
+index 0000000..b93d317
+--- /dev/null
++++ b/docs/apitrace_test.markdown
+@@ -0,0 +1,125 @@
++Gpu driver: 5.0.11p4 and later
++
++Package: gpu-south-tools-release
++
++
++## Install tools
++
++### Yocto
++
++Installed by default. If not, use following command to install:
++
++```
++cp gpu-south-tools-release/0.1/apitrace/linux/yocto/bin/* /usr/bin
++cp -r gpu-south-tools-release/0.1/apitrace/linux/yocto/lib/apitrace /usr/lib
++cp -r gpu-south-tools-release/0.1/apitrace/linux/yocto/share/doc/apitrace/ /usr/share/doc/
++```
++
++And copy gpu-south-tools-release/0.1/apitrace/linux/yocto/test to some place for auto test.
++
++### Android
++
++In COM terminal, which has root privilege, mount the release package to android
++system:
++
++```
++mkdir /data/share; busybox mount -t nfs -o nolock 10.192.241.131:/home/zhenyong/share /data/share
++cp -r gpu-south-tools-release/0.1/apitrace/android/apitrace /data/
++```
++
++### PC-linux-x64
++
++```
++cp gpu-south-tools-release/0.1/apitrace/linux/x64/bin/* /usr/bin
++cp -r gpu-south-tools-release/0.1/apitrace/linux/x64/lib/apitrace /usr/lib
++cp -r gpu-south-tools-release/0.1/apitrace/linux/x64/share/doc/apitrace/ /usr/share/doc/
++```
++
++
++## Test content
++
++For x11/fb/dfb/wayland, both apitrace and retrace need test.
++For android, only apitrace is test. The dumped trace file need replay on
++i.mx6q-x11 device. Dumped files are stored under /sdcard/.
++For x64-linux, only qapitrace is to test.
++
++
++## Test instructions
++
++### Yocto
++
++Run:
++```
++gpu-south-tools-release/0.1/apitrace/test_yocto.sh
++```
++
++### Android
++
++auto	sh /data/apitrace/test/test_android.sh
++manual	sh /data/apitrace/bin/apitrace_dalvik.sh com.android.settings start
++	<operation with com.android.settings>
++	sh /data/apitrace/bin/apitrace_dalvik.sh com.android.settings stop
++
++Download trace files:
++```
++adb shell busybox find /sdcard/ -name "*.trace" | tr -d '\015' | while read FILE; do adb pull $FILE ./; done
++```
++
++Replay on yocto:
++```
++eglretrace *.trace
++```
++
++Caution: trace file requires a lot of disk space, so reserve at least 1 GB.
++
++
++## Test result
++
++No crash, no failure, and retrace is correct, and dumped trace file can be
++ opened by qapitrace on x64-linux.
++
++
++## Test cases
++
++```
+++---------------+-----------------------+
++|               | angeles               |
++| OpenGL ES 1.1 | tritex                |
++|               | textures              |
++|               | OGLESCoverflow        |
++|               | tutorial1             |
++|               | tutorial2             |
++|               | tutorial3             |
++|               | tutorial4             |
++|               | tutorial5             |
++|               | tutorial6             |
++|               | tutorial7             |
+++---------------+-----------------------+
++|               | es2gears              |
++| OpenGL ES 2.0 | OGLES2Coverflow       |
++|               | OGLES2Fog             |
++|               | OGLES2Texturing       |
++|               | scene_FBO             |
++|               | glimagesink           |
++|               | glmark2-es2           |
++|               | tutorial1_es20        |
++|               | tutorial2_es20        |
++|               | tutorial3_es20        |
++|               | tutorial4_es20        |
++|               | tutorial5_es20        |
++|               | tutorial6_es20        |
++|               | tutorial7_es20        |
++|               | com.android.gallery3d |
+++---------------+-----------------------+
++|               | OGLES3PhantomMask     |
++| OpenGL ES 3.0 | OGLES3DeferredShading |
++|               | OGLES3RenderToTexture |
+++---------------+-----------------------+
++|               | glxgears              |
++| OpenGL        | glmark2               |
++|               | glxs                  |
+++---------------+-----------------------+
++| OpenVG        | tiger                 |
++|               | vgmark_10             |
+++---------------+-----------------------+
++```
+-- 
+2.7.4
+
diff --git a/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0005-add-apitrace_dalvik.sh.patch b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0005-add-apitrace_dalvik.sh.patch
new file mode 100644
index 0000000..1b0e8aa
--- /dev/null
+++ b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0005-add-apitrace_dalvik.sh.patch
@@ -0,0 +1,75 @@
+From 80c17e1d0c28e1a78abbc57c484ce09133a66000 Mon Sep 17 00:00:00 2001
+From: Yuchou Gan <yuchou.gan at nxp.com>
+Date: Thu, 19 Jan 2017 09:24:35 +0200
+Subject: [PATCH 05/31] add apitrace_dalvik.sh
+
+---
+ apitrace_dalvik.sh | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 56 insertions(+)
+ create mode 100644 apitrace_dalvik.sh
+
+diff --git a/apitrace_dalvik.sh b/apitrace_dalvik.sh
+new file mode 100644
+index 0000000..107d0fc
+--- /dev/null
++++ b/apitrace_dalvik.sh
+@@ -0,0 +1,56 @@
++#! /system/bin/sh
++
++# Copyright (c) 2014, Freescale Semiconductor Inc.
++# All rights reserved.
++#
++# You should get a copy of license in this software package named EULA.txt.
++# Please read EULA.txt carefully first.
++
++
++
++
++# This script is used on Android to instrument non-native Android applications.
++# For native Android applications, you can use "apitrace" as on Linux.
++#
++# Install this package under /data.
++# The .trace files will be stored under /sdcard/.
++
++# If install this package to other place, please update INSTALL in this file
++
++if [ $# != 2 ] || [ "$2" != "start" -a "$2" != "stop" ]; then
++	echo "$0 <component> <start|stop>"
++	log -t apitrace "$0 <component> <start|stop>"
++	exit 1
++fi
++
++PROCNAME=$1
++INSTALL=/data/apitrace
++
++if [ "$2" == "start" ]; then
++	if [ -e $INSTALL/lib/apitrace/wrappers/egltrace.so ]; then
++		# TODO: check normal user can access this path or not
++		setprop wrap.$PROCNAME LD_PRELOAD=$INSTALL/lib/apitrace/wrappers/egltrace.so
++	else
++		# default
++		setprop wrap.$PROCNAME LD_PRELOAD=/system/lib/egltrace.so
++	fi
++
++	setprop debug.apitrace.procname $PROCNAME
++
++	log -t apitrace "Stop $PROCNAME/.main_dummy"
++	am start -S $PROCNAME/.main_dummy
++	sleep 5
++
++	log -t apitrace "Start $PROCNAME"
++	am start $PROCNAME
++fi
++
++if [ "$2" == "stop" ]; then
++	log -t apitrace "Stop $PROCNAME tracing"
++	log -t apitrace "Stop $PROCNAME/.main_dummy"
++	am start -S $PROCNAME/.main_dummy
++	setprop wrap.$PROCNAME ""
++	setprop debug.apitrace.procname ""
++fi
++
++exit 0
+-- 
+2.7.4
+
diff --git a/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0006-add-test_android.sh.patch b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0006-add-test_android.sh.patch
new file mode 100644
index 0000000..6af1943
--- /dev/null
+++ b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0006-add-test_android.sh.patch
@@ -0,0 +1,72 @@
+From a2ac34d5b0dca60fa98555801f3e021f5f21c464 Mon Sep 17 00:00:00 2001
+From: Yuchou Gan <yuchou.gan at nxp.com>
+Date: Thu, 19 Jan 2017 09:39:20 +0200
+Subject: [PATCH 06/31] add test_android.sh
+
+---
+ test_android.sh | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 53 insertions(+)
+ create mode 100644 test_android.sh
+
+diff --git a/test_android.sh b/test_android.sh
+new file mode 100644
+index 0000000..b6cfb9f
+--- /dev/null
++++ b/test_android.sh
+@@ -0,0 +1,53 @@
++#!/system/bin/sh
++
++INSTALL=/data/apitrace
++TRACEFILE_PATH=/sdcard/
++MAXDURATION="10" # duration for every case. depending on available disk space
++
++EGL11_CASES="angeles test-opengl-tritex test-opengl-textures"
++
++kill_app()
++{
++    APP=$1
++    # Need truncate app name, otherwise pkill will fail on yocto
++    busybox pkill -x "${APP:0:15}"
++}
++
++run_eglcases()
++{
++    for tcase in $1
++    do
++        CURPATH="$(realpath .)"
++        echo "--------------------------------------------------------"
++	echo "Start apitrace"
++        echo "--------------------------------------------------------"
++        # start test
++	apitrace trace -v --output=$TRACEFILE_PATH/$tcase.trace --api=egl $tcase &
++        sleep $MAXDURATION
++        # end test
++	kill_app $tcase
++        cd $CURPATH # go back to original path
++    done
++}
++
++run_cases()
++{
++    export PATH=$PATH:$INSTALL/bin:$INSTALL/test
++
++    echo "Put trace file to $TRACEFILE_PATH"
++
++    mkdir -p $TRACEFILE_PATH
++    rm $TRACEFILE_PATH/*.trace
++
++    run_eglcases "$EGL11_CASES"
++}
++
++date
++
++run_cases
++
++echo "--------------------------------------------------------"
++echo "Test finished"
++date
++echo "--------------------------------------------------------"
++exit 0
+-- 
+2.7.4
+
diff --git a/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0007-add-test_yocto.sh.patch b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0007-add-test_yocto.sh.patch
new file mode 100644
index 0000000..b3272e9
--- /dev/null
+++ b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0007-add-test_yocto.sh.patch
@@ -0,0 +1,131 @@
+From c2f2546ad9f4139c278630d8ddacd462de8aec8e Mon Sep 17 00:00:00 2001
+From: Yuchou Gan <yuchou.gan at nxp.com>
+Date: Thu, 19 Jan 2017 09:40:19 +0200
+Subject: [PATCH 07/31] add test_yocto.sh
+
+---
+ test_yocto.sh | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 112 insertions(+)
+ create mode 100644 test_yocto.sh
+
+diff --git a/test_yocto.sh b/test_yocto.sh
+new file mode 100644
+index 0000000..805ccaf
+--- /dev/null
++++ b/test_yocto.sh
+@@ -0,0 +1,112 @@
++#! /bin/bash
++
++# tool to auto-test apitrace/retrace on linux-yocto
++# this tool support x11/fb/dfb/wayland backends
++
++if [ $# != 2 ]; then
++    echo "Usage: $0 <backend> <tracefile path>"
++    echo "    backend: can be one of fb/dfb/wayland/x11"
++    echo "    tracefile path: where to put trace file"
++    exit -1
++fi
++
++BACKEND=$1
++TRACEFILE_PATH="$(realpath $2)"
++MAXDURATION="10s" # duration for every case. depending on available disk space
++
++EGL11_CASES="angeles tritex OGLESCoverflow tutorial1 tutorial2 tutorial3 tutorial4 tutorial5 tutorial6 tutorial7"
++EGL20_CASES="es2gears OGLES2Coverflow OGLES2Fog OGLES2Texturing scene_FBO glmark2-es2 tutorial1_es20 tutorial2_es20 tutorial3_es20 tutorial4_es20 tutorial5_es20 tutorial6_es20 tutorial7_es20"
++EGL30_CASES="OGLES3PhantomMask OGLES3DeferredShading OGLES3RenderToTexture"
++#GLX_CASES="glxgears glmark2 glxs"
++GLX_CASES="glxgears glxs"
++
++kill_app()
++{
++    APP=$1
++    # Need truncate app name, otherwise pkill will fail on yocto
++    pkill -x "${APP:0:15}"
++}
++
++run_eglcases()
++{
++    for tcase in $1
++    do
++        CURPATH="$(realpath .)"
++        echo "--------------------------------------------------------"
++	echo "Start apitrace"
++        echo "--------------------------------------------------------"
++        # for tutorial cases, need go to that directory to run
++	if [ "${tcase:0:8}" == "tutorial" ]; then
++            cd /opt/viv_samples/vdk
++	fi
++        # start test
++	apitrace trace --output=$TRACEFILE_PATH/$tcase.trace --api=egl $tcase &
++        sleep $MAXDURATION
++        # end test
++	kill_app $tcase
++        cd $CURPATH # go back to original path
++
++	echo "--------------------------------------------------------"
++	echo "Start retrace"
++        echo "--------------------------------------------------------"
++	sleep 1s
++        eglretrace $TRACEFILE_PATH/$tcase.trace
++    done
++}
++
++run_glxcases()
++{
++    for tcase in $1
++    do
++        CURPATH="$(realpath .)"
++	echo "--------------------------------------------------------"
++	echo "Start apitrace"
++        echo "--------------------------------------------------------"
++
++	if [ "$tcase" == "glxs" ]; then
++            cd /share/X11Tests/yocto1.6rel/bin/GLXS
++	    tcase="./$tcase"
++	fi
++
++        # start test
++	apitrace trace --output=$TRACEFILE_PATH/$tcase.trace --api=gl $tcase &
++        sleep $MAXDURATION
++        # end test
++	kill_app $tcase
++        cd $CURPATH # go back to original path
++
++	echo "--------------------------------------------------------"
++	echo "Start retrace"
++        echo "--------------------------------------------------------"
++	sleep 1s
++        glretrace $TRACEFILE_PATH/$tcase.trace
++    done
++}
++
++run_cases()
++{
++    export PATH=$PATH:/share/X11Tests/yocto1.6rel/bin:/opt/viv_samples/vdk
++    export PATH=$PATH:/share/X11Tests/yocto1.6rel/bin/PowerVR3.1/Advanced/:/share/X11Tests/yocto1.6rel/bin/PowerVR3.1/Intermediate/:/share/X11Tests/yocto1.6rel/bin/PowerVR3.1/Beginner/
++    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/share/X11Tests/yocto1.6rel/lib
++    if [ "$BACKEND" == "x11" ]; then
++    export DISPLAY=:0
++    fi
++    mkdir -p $TRACEFILE_PATH
++    rm $TRACEFILE_PATH/*.trace
++
++    run_eglcases "$EGL11_CASES"
++    run_eglcases "$EGL20_CASES"
++    run_eglcases "$EGL30_CASES"
++    if [ "$BACKEND" == "x11" ]; then
++    run_glxcases "$GLX_CASES"
++    fi
++}
++
++date
++
++run_cases
++
++echo "--------------------------------------------------------"
++echo "Test finished"
++date
++echo "--------------------------------------------------------"
+-- 
+2.7.4
+
diff --git a/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0008-docs-mention-apitrace_dalvik.sh.patch b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0008-docs-mention-apitrace_dalvik.sh.patch
new file mode 100644
index 0000000..7df7466
--- /dev/null
+++ b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0008-docs-mention-apitrace_dalvik.sh.patch
@@ -0,0 +1,28 @@
+From 9cac54ef85833b55095a8115ecbf059b6d4e23c3 Mon Sep 17 00:00:00 2001
+From: Adrian Negreanu <groleo at gmail.com>
+Date: Wed, 29 Mar 2017 14:36:19 +0300
+Subject: [PATCH 08/31] docs: mention apitrace_dalvik.sh
+
+---
+ docs/Dalvik.markdown | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/docs/Dalvik.markdown b/docs/Dalvik.markdown
+index 6fddf38..0224e7e 100644
+--- a/docs/Dalvik.markdown
++++ b/docs/Dalvik.markdown
+@@ -42,6 +42,11 @@ are saved into '/data/data/$PROCNAME' directory by default:
+     adb shell rm /data/data/$PROCNAME/$PROCNAME.trace
+ 
+ 
++## Helper script ##
++
++    sh /sdcard/apitrace/bin/apitrace_dalvik.sh com.android.settings
++
++
+ ## Tracing on Android pre-4.0 ##
+ 
+ `LD_PRELOAD` is supported since Android 2.3 "Gingerbread" and newer, but
+-- 
+2.7.4
+
diff --git a/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0009-add-retrace-glws_nonx.cpp.patch b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0009-add-retrace-glws_nonx.cpp.patch
new file mode 100644
index 0000000..a50192f
--- /dev/null
+++ b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0009-add-retrace-glws_nonx.cpp.patch
@@ -0,0 +1,515 @@
+From c44f18c4ae1098a5ff2afb98eb3f1c2d1b0fe7e5 Mon Sep 17 00:00:00 2001
+From: Gan Yuchou <yuchou.gan at nxp.com>
+Date: Mon, 23 Jan 2017 12:27:25 +0200
+Subject: [PATCH 09/31] add retrace/glws_nonx.cpp
+
+Signed-off-by: Gan Yuchou <yuchou.gan at nxp.com>
+---
+ retrace/glws_nonx.cpp | 495 ++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 495 insertions(+)
+ create mode 100644 retrace/glws_nonx.cpp
+
+diff --git a/retrace/glws_nonx.cpp b/retrace/glws_nonx.cpp
+new file mode 100644
+index 0000000..fa8db97
+--- /dev/null
++++ b/retrace/glws_nonx.cpp
+@@ -0,0 +1,495 @@
++// This file is to support: FB/DFB/Wayland retrace
++
++#include <assert.h>
++#include <stdlib.h>
++
++#include <iostream>
++
++#include <dlfcn.h>
++
++#include "glproc.hpp"
++#include "glws.hpp"
++
++#include <EGL/eglext.h>
++#include "gc_vdk.h"
++
++namespace glws {
++
++static vdkEGL vdk_egl;
++static char const *eglExtensions = NULL;
++static bool has_EGL_KHR_create_context = false;
++static bool check_dfb();
++
++static EGLenum
++translateAPI(glprofile::Profile profile)
++{
++    switch (profile.api) {
++    case glprofile::API_GL:
++        return EGL_OPENGL_API;
++    case glprofile::API_GLES:
++        return EGL_OPENGL_ES_API;
++    default:
++        assert(0);
++        return EGL_NONE;
++    }
++}
++
++
++/* Must be called before
++ *
++ * - eglCreateContext
++ * - eglGetCurrentContext
++ * - eglGetCurrentDisplay
++ * - eglGetCurrentSurface
++ * - eglMakeCurrent (when its ctx parameter is EGL_NO_CONTEXT ),
++ * - eglWaitClient
++ * - eglWaitNative
++ */
++static void
++bindAPI(EGLenum api)
++{
++    if (eglBindAPI(api) != EGL_TRUE) {
++        std::cerr << "error: eglBindAPI failed\n";
++        exit(1);
++    }
++}
++
++class NonxVisual : public Visual
++{
++public:
++    EGLConfig config;
++
++    NonxVisual(Profile prof, EGLConfig cfg) :
++        Visual(prof),
++        config(cfg)
++    {}
++
++    virtual ~NonxVisual() {
++    }
++};
++
++class NonxDrawable : public Drawable
++{
++public:
++    EGLNativePixmapType native_pixmap;
++    EGLenum api;
++
++    NonxDrawable(const Visual *vis, int w, int h, bool pbuffer) :
++        Drawable (vis, w, h, pbuffer),
++        api(EGL_OPENGL_ES_API)
++    {
++        native_pixmap = (EGLNativePixmapType)0;
++        createVDKDrawable(w, h);
++    }
++
++    virtual ~NonxDrawable()
++    {
++        destroyVDKDrawable();
++    }
++
++    void
++    createVDKDrawable(int w, int h, bool pixmap = false) {
++        if(check_dfb()) {
++            int width, height, stride, bpp;
++            unsigned long phy;
++            vdkGetDisplayInfo(vdk_egl.display, &width, &height, &phy, &stride, &bpp);
++            Drawable::resize(width, height);
++            w = width;
++            h = height;
++        }
++        vdk_egl.window = vdkCreateWindow(vdk_egl.display, 0, 0, w, h);
++
++        EGLConfig config = static_cast<const NonxVisual *>(visual)->config;
++
++        if(pixmap)
++        {
++            native_pixmap = vdkCreatePixmap(vdk_egl.display, w, h, 32);
++            vdk_egl.eglSurface = eglCreatePixmapSurface(vdk_egl.eglDisplay, config, native_pixmap, NULL);
++            if(vdk_egl.eglSurface == EGL_NO_SURFACE) {
++               std::cerr << "error: failed to create pixmap surface:" << eglGetError() << "\n";
++               exit(1);
++            }
++            std::cerr<<"@@@@create eglPixmapSurface:" << vdk_egl.eglSurface << "\n";
++        }
++
++        else {
++            eglWaitNative(EGL_CORE_NATIVE_ENGINE);
++            vdk_egl.eglSurface = eglCreateWindowSurface(vdk_egl.eglDisplay, config, (EGLNativeWindowType)vdk_egl.window, NULL);
++            if(vdk_egl.eglSurface == EGL_NO_SURFACE) {
++                std::cerr << "error: failed to create window surface\n";
++                exit(1);
++            }
++        }
++
++        vdkSetWindowTitle(vdk_egl.window, "retrace");
++        vdkShowWindow(vdk_egl.window);
++
++        std::cerr << "window size " << w << " x " << h << "\n";
++    }
++
++    void
++    destroyVDKDrawable(void) {
++        if(vdk_egl.eglSurface != EGL_NO_SURFACE) {
++            eglDestroySurface(vdk_egl.eglDisplay, vdk_egl.eglSurface);
++            eglWaitClient();
++            vdk_egl.eglSurface = EGL_NO_SURFACE;
++        }
++        if(native_pixmap != NULL) {
++            vdkDestroyPixmap(native_pixmap);
++            native_pixmap = NULL;
++        }
++        if(vdk_egl.window != NULL) {
++            /* Hide the window. */
++            vdkHideWindow(vdk_egl.window);
++            /* Destroy the window. */
++            vdkDestroyWindow(vdk_egl.window);
++            vdk_egl.window = NULL;
++            eglWaitNative(EGL_CORE_NATIVE_ENGINE);
++        }
++    }
++
++    void
++    resize(int w, int h) {
++        if (w == width && h == height) {
++            return;
++        }
++
++        eglWaitClient();
++        /* Hide the window. */
++        vdkHideWindow(vdk_egl.window);
++        /* Destroy the window. */
++        vdkDestroyWindow(vdk_egl.window);
++        vdk_egl.window = NULL;
++        eglWaitNative(EGL_CORE_NATIVE_ENGINE);
++
++        vdk_egl.window = vdkCreateWindow(vdk_egl.display, 0, 0, w, h);
++        EGLContext currentContext = eglGetCurrentContext();
++        EGLConfig config = static_cast<const NonxVisual *>(visual)->config;
++        EGLSurface oldSurface = vdk_egl.eglSurface;
++        vdk_egl.eglSurface = eglCreateWindowSurface(vdk_egl.eglDisplay, config, (EGLNativeWindowType)vdk_egl.window, NULL);
++        eglMakeCurrent(vdk_egl.eglDisplay, vdk_egl.eglSurface, vdk_egl.eglSurface, currentContext);
++        eglDestroySurface(vdk_egl.eglDisplay, oldSurface);
++
++        vdkSetWindowTitle(vdk_egl.window, "retrace");
++        vdkShowWindow(vdk_egl.window);
++
++        std::cerr << "window resize " << w << " x " << h << "\n";
++        Drawable::resize(w, h);
++    }
++
++    void
++    show(void) {
++        if (visible) {
++            return;
++        }
++
++        eglWaitClient();
++
++        vdkShowWindow(vdk_egl.window);
++
++        eglWaitNative(EGL_CORE_NATIVE_ENGINE);
++
++        Drawable::show();
++    }
++
++    void
++    swapBuffers(void) {
++        bindAPI(api);
++        vdkSwapEGL(&vdk_egl);
++    }
++};
++
++class NonxContext : public Context
++{
++public:
++    EGLContext context;
++
++    NonxContext(const Visual *vis, EGLContext ctx) :
++        Context(vis),
++        context(ctx)
++    {}
++
++    virtual ~NonxContext() {
++        eglDestroyContext(vdk_egl.eglDisplay, context);
++    }
++};
++
++/**
++ * Load the symbols from the specified shared object into global namespace, so
++ * that they can be later found by dlsym(RTLD_NEXT, ...);
++ */
++static void
++load(const char *filename)
++{
++    if (!dlopen(filename, RTLD_GLOBAL | RTLD_LAZY)) {
++        std::cerr << "error: unable to open " << filename << "\n";
++        exit(1);
++    }
++}
++
++static bool
++check_dfb() {
++    static int status = -1;
++    if(status != -1)
++        return (status == 1);
++
++    void *h = dlopen("libdirectfb_gal.so", RTLD_GLOBAL | RTLD_LAZY);
++    if (h == NULL) {
++        status = 0;
++        return false;
++    }
++
++    std::cerr << "It is DirectFB\n";
++
++    dlclose(h);
++    status = 1;
++    return true;
++}
++
++void
++init(void) {
++    load("libEGL.so.1");
++
++    vdk_egl.vdk = vdkInitialize();
++    if(vdk_egl.vdk == 0) {
++        std::cerr << "error: failed to init vdk\n";
++        exit(1);
++    }
++    // vdk display as native display
++    vdk_egl.display = vdkGetDisplay(vdk_egl.vdk);
++    std::cerr << "native display: " << vdk_egl.display << "\n";
++
++    vdk_egl.eglDisplay = eglGetDisplay(vdk_egl.display);
++    if (vdk_egl.eglDisplay == EGL_NO_DISPLAY) {
++        std::cerr << "error: unable to get EGL display\n";
++        exit(1);
++    }
++
++    EGLint major, minor;
++    if (!eglInitialize(vdk_egl.eglDisplay, &major, &minor)) {
++        std::cerr << "error: unable to initialize EGL display\n";
++        exit(1);
++    }
++
++    eglExtensions = eglQueryString(vdk_egl.eglDisplay, EGL_EXTENSIONS);
++    has_EGL_KHR_create_context = checkExtension("EGL_KHR_create_context", eglExtensions);
++
++}
++
++void
++cleanup(void) {
++    if (vdk_egl.eglDisplay != EGL_NO_DISPLAY) {
++        eglTerminate(vdk_egl.eglDisplay);
++    }
++    vdkDestroyDisplay(vdk_egl.display);
++    vdkExit(vdk_egl.vdk);
++}
++
++Visual *
++createVisual(bool doubleBuffer, unsigned samples, Profile profile) {
++    EGLint api_bits;
++    if (profile.api == glprofile::API_GL) {
++        api_bits = EGL_OPENGL_BIT;
++        if (profile.core && !has_EGL_KHR_create_context) {
++            return NULL;
++        }
++    } else if (profile.api == glprofile::API_GLES) {
++        switch (profile.major) {
++        case 1:
++            api_bits = EGL_OPENGL_ES_BIT;
++            break;
++        case 3:
++            if (has_EGL_KHR_create_context) {
++                api_bits = EGL_OPENGL_ES3_BIT;
++                break;
++            }
++            /* fall-through */
++        case 2:
++            api_bits = EGL_OPENGL_ES2_BIT;
++            break;
++        default:
++            return NULL;
++        }
++    } else {
++        assert(0);
++        return NULL;
++    }
++
++    Attributes<EGLint> attribs;
++    attribs.add(EGL_SURFACE_TYPE, EGL_WINDOW_BIT);
++    attribs.add(EGL_RED_SIZE, 1);
++    attribs.add(EGL_GREEN_SIZE, 1);
++    attribs.add(EGL_BLUE_SIZE, 1);
++    attribs.add(EGL_ALPHA_SIZE, 1);
++    attribs.add(EGL_DEPTH_SIZE, 1);
++    attribs.add(EGL_STENCIL_SIZE, 1);
++    attribs.add(EGL_RENDERABLE_TYPE, api_bits);
++    attribs.end(EGL_NONE);
++
++    EGLint num_configs = 0;
++    if (!eglGetConfigs(vdk_egl.eglDisplay, NULL, 0, &num_configs) ||
++        num_configs <= 0) {
++        return NULL;
++    }
++
++    std::vector<EGLConfig> configs(num_configs);
++    if (!eglChooseConfig(vdk_egl.eglDisplay, attribs, &configs[0], num_configs,  &num_configs) ||
++        num_configs <= 0) {
++        return NULL;
++    }
++
++    // We can't tell what other APIs the trace will use afterwards, therefore
++    // try to pick a config which supports the widest set of APIs.
++    int bestScore = -1;
++    EGLConfig config = configs[0];
++    for (EGLint i = 0; i < num_configs; ++i) {
++        EGLint renderable_type = EGL_NONE;
++        eglGetConfigAttrib(vdk_egl.eglDisplay, configs[i], EGL_RENDERABLE_TYPE, &renderable_type);
++        int score = 0;
++        assert(renderable_type & api_bits);
++        renderable_type &= ~api_bits;
++        if (renderable_type & EGL_OPENGL_ES2_BIT) {
++            score += 1 << 4;
++        }
++        if (renderable_type & EGL_OPENGL_ES3_BIT) {
++            score += 1 << 3;
++        }
++        if (renderable_type & EGL_OPENGL_ES_BIT) {
++            score += 1 << 2;
++        }
++        if (renderable_type & EGL_OPENGL_BIT) {
++            score += 1 << 1;
++        }
++        if (score > bestScore) {
++            config = configs[i];
++            bestScore = score;
++        }
++    }
++    assert(bestScore >= 0);
++
++    EGLint visual_id;
++    if (!eglGetConfigAttrib(vdk_egl.eglDisplay, config, EGL_NATIVE_VISUAL_ID, &visual_id)) {
++        assert(0);
++        return NULL;
++    }
++
++    Visual *visual = NULL;
++
++    if(config != 0) {
++        std::cerr << "eglChooseConfig ok\n";
++        visual = new NonxVisual(profile, config);
++    }
++    else {
++        std::cerr << "error: failed to get egl config\n";
++    }
++
++    return visual;
++}
++
++Drawable *
++createDrawable(const Visual *visual, int width, int height, bool pbuffer)
++{
++    return new NonxDrawable(visual, width, height, pbuffer);
++}
++
++Context *
++createContext(const Visual *_visual, Context *shareContext, bool debug)
++{
++    Profile profile = _visual->profile;
++    const NonxVisual *visual = static_cast<const NonxVisual *>(_visual);
++    EGLContext share_context = EGL_NO_CONTEXT;
++    EGLContext context;
++    Attributes<EGLint> attribs;
++
++    if (shareContext) {
++        share_context = static_cast<NonxContext*>(shareContext)->context;
++    }
++
++    int contextFlags = 0;
++    if (profile.api == glprofile::API_GL) {
++        load("libGL.so.1");
++
++        if (has_EGL_KHR_create_context) {
++            attribs.add(EGL_CONTEXT_MAJOR_VERSION_KHR, profile.major);
++            attribs.add(EGL_CONTEXT_MINOR_VERSION_KHR, profile.minor);
++            int profileMask = profile.core ? EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR : EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR;
++            attribs.add(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, profileMask);
++            if (profile.forwardCompatible) {
++                contextFlags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
++            }
++        } else if (profile.versionGreaterOrEqual(3, 2)) {
++            std::cerr << "error: EGL_KHR_create_context not supported\n";
++            return NULL;
++        }
++    } else if (profile.api == glprofile::API_GLES) {
++        if (profile.major >= 2) {
++            load("libGLESv2.so.2");
++        } else {
++            load("libGLESv1_CM.so.1");
++        }
++
++        if (has_EGL_KHR_create_context) {
++            attribs.add(EGL_CONTEXT_MAJOR_VERSION_KHR, profile.major);
++            attribs.add(EGL_CONTEXT_MINOR_VERSION_KHR, profile.minor);
++        } else {
++            attribs.add(EGL_CONTEXT_CLIENT_VERSION, profile.major);
++        }
++    } else {
++        assert(0);
++        return NULL;
++    }
++
++    if (debug) {
++        contextFlags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR;
++    }
++    if (contextFlags && has_EGL_KHR_create_context) {
++        attribs.add(EGL_CONTEXT_FLAGS_KHR, contextFlags);
++    }
++    attribs.end(EGL_NONE);
++
++    EGLenum api = translateAPI(profile);
++    bindAPI(api);
++
++    context = eglCreateContext(vdk_egl.eglDisplay, visual->config, share_context, attribs);
++    if (!context) {
++        if (debug) {
++            // XXX: Mesa has problems with EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR
++            // with OpenGL ES contexts, so retry without it
++            return createContext(_visual, shareContext, false);
++        }
++        return NULL;
++    }
++    return new NonxContext(visual, context);
++}
++
++bool
++makeCurrentInternal(Drawable *drawable, Context *context)
++{
++    if (!drawable || !context) {
++        return eglMakeCurrent(vdk_egl.eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
++    } else {
++        NonxDrawable *eglDrawable = static_cast<NonxDrawable *>(drawable);
++        NonxContext *eglContext = static_cast<NonxContext *>(context);
++        EGLBoolean ok;
++
++        EGLenum api = translateAPI(eglContext->profile);
++        bindAPI(api);
++
++        ok = eglMakeCurrent(vdk_egl.eglDisplay, vdk_egl.eglSurface,
++                            vdk_egl.eglSurface, eglContext->context);
++
++        if (ok) {
++            eglDrawable->api = api;
++        }
++
++        return ok;
++    }
++}
++
++bool
++processEvents(void)
++{
++    return false;
++}
++
++}
+-- 
+2.7.4
+
diff --git a/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0010-cmake-use-glws_nonx-for-Vivante.patch b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0010-cmake-use-glws_nonx-for-Vivante.patch
new file mode 100644
index 0000000..0112c29
--- /dev/null
+++ b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0010-cmake-use-glws_nonx-for-Vivante.patch
@@ -0,0 +1,62 @@
+From c0e8e603ef8b65ac039a2699554025661a3f62d2 Mon Sep 17 00:00:00 2001
+From: Adrian Negreanu <groleo at gmail.com>
+Date: Mon, 23 Jan 2017 12:27:56 +0200
+Subject: [PATCH 10/31] cmake: use glws_nonx for Vivante
+
+The nonX windowing system gets used when Apitrace is compiled
+
+with:
+   EGL
+
+and without:
+   X11
+   Win32
+   Apple
+   Waffle
+   Android
+---
+ retrace/CMakeLists.txt | 28 ++++++++++++++++++++++++++++
+ 1 file changed, 28 insertions(+)
+
+diff --git a/retrace/CMakeLists.txt b/retrace/CMakeLists.txt
+index cce69e1..9973e2c 100644
+--- a/retrace/CMakeLists.txt
++++ b/retrace/CMakeLists.txt
+@@ -158,6 +158,34 @@ if (ENABLE_EGL AND X11_FOUND AND NOT WIN32 AND NOT APPLE AND NOT ENABLE_WAFFLE)
+     install (TARGETS eglretrace RUNTIME DESTINATION bin) 
+ endif ()
+ 
++if (Vivante_FOUND AND ENABLE_EGL AND NOT X11_FOUND AND NOT WIN32 AND NOT APPLE AND NOT ENABLE_WAFFLE AND NOT ANDROID)
++    add_executable (eglretrace
++        glws_nonx.cpp
++    )
++
++    add_dependencies (eglretrace glproc)
++    include_directories (${CMAKE_SYSROOT}/usr/include/HAL/)
++
++    target_link_libraries (eglretrace
++        retrace_common
++        glretrace_common
++        glhelpers
++        glproc_egl
++        ${CMAKE_THREAD_LIBS_INIT}
++        ${CMAKE_DL_LIBS}
++        VDK
++    )
++
++    if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
++        target_link_libraries (eglretrace rt)
++        if (READPROC_H_FOUND)
++            target_link_libraries (eglretrace ${proc_LIBRARY})
++        endif ()
++    endif ()
++
++    install (TARGETS eglretrace RUNTIME DESTINATION bin)
++endif ()
++
+ if (ENABLE_EGL)
+     if (ENABLE_WAFFLE)
+         add_executable (eglretrace
+-- 
+2.7.4
+
diff --git a/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0011-cli_trace-export-ENABLE_API_TRACE-1.patch b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0011-cli_trace-export-ENABLE_API_TRACE-1.patch
new file mode 100644
index 0000000..93aaff7
--- /dev/null
+++ b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0011-cli_trace-export-ENABLE_API_TRACE-1.patch
@@ -0,0 +1,37 @@
+From 117de34b35888fc4dbacb394216c5127461778df Mon Sep 17 00:00:00 2001
+From: Yuchou Gan <yuchou.gan at nxp.com>
+Date: Thu, 19 Jan 2017 09:52:31 +0200
+Subject: [PATCH 11/31] cli_trace: export ENABLE_API_TRACE=1
+
+No description of what the variable is for.
+---
+ cli/cli_trace.cpp | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/cli/cli_trace.cpp b/cli/cli_trace.cpp
+index adca8af..ea57878 100644
+--- a/cli/cli_trace.cpp
++++ b/cli/cli_trace.cpp
+@@ -251,6 +251,8 @@ traceProgram(trace::API api,
+             os::setEnvironment("TRACE_FILE", output);
+         }
+ 
++        os::setEnvironment("ENABLE_API_TRACE", "1");
++
+         for (char * const * arg = argv; *arg; ++arg) {
+             args.push_back(*arg);
+         }
+@@ -296,7 +298,9 @@ exit:
+     if (output) {
+         os::unsetEnvironment("TRACE_FILE");
+     }
+-    
++
++    os::unsetEnvironment("ENABLE_API_TRACE");
++
+     return status;
+ 
+ }
+-- 
+2.7.4
+
diff --git a/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0012-use-dlsym-to-get-function-pointers.patch b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0012-use-dlsym-to-get-function-pointers.patch
new file mode 100644
index 0000000..aa6272d
--- /dev/null
+++ b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0012-use-dlsym-to-get-function-pointers.patch
@@ -0,0 +1,31 @@
+From b3e71db97c981fcb91eb6beaa6a7941fccdc25fc Mon Sep 17 00:00:00 2001
+From: Yuchou Gan <yuchou.gan at nxp.com>
+Date: Thu, 19 Jan 2017 09:58:51 +0200
+Subject: [PATCH 12/31] use dlsym to get function pointers
+
+---
+ dispatch/glproc_gl.cpp | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/dispatch/glproc_gl.cpp b/dispatch/glproc_gl.cpp
+index 8ae40d4..7d162da 100644
+--- a/dispatch/glproc_gl.cpp
++++ b/dispatch/glproc_gl.cpp
+@@ -221,7 +221,13 @@ _getPublicProcAddress(const char *procName)
+ void *
+ _getPrivateProcAddress(const char *procName)
+ {
+-    return (void *)_glXGetProcAddressARB((const GLubyte *)procName);
++    void *proc;
++    proc = _getPublicProcAddress(procName);
++    if (!proc) {
++        proc = (void *)_glXGetProcAddressARB((const GLubyte *)procName);
++    }
++
++    return proc;
+ }
+ 
+ 
+-- 
+2.7.4
+
diff --git a/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0013-Vivante-driver-does-not-support-GL_RGB-in-openGL-dri.patch b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0013-Vivante-driver-does-not-support-GL_RGB-in-openGL-dri.patch
new file mode 100644
index 0000000..6a78fd7
--- /dev/null
+++ b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0013-Vivante-driver-does-not-support-GL_RGB-in-openGL-dri.patch
@@ -0,0 +1,36 @@
+From 58ba383c0f51b02ebcf703c1d8a3e213dc08ae97 Mon Sep 17 00:00:00 2001
+From: Yuchou Gan <yuchou.gan at nxp.com>
+Date: Thu, 19 Jan 2017 11:37:50 +0200
+Subject: [PATCH 13/31] Vivante driver does not support GL_RGB in openGL driver
+
+---
+ retrace/glstate_images.cpp | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/retrace/glstate_images.cpp b/retrace/glstate_images.cpp
+index 44a2633..f0805e2 100644
+--- a/retrace/glstate_images.cpp
++++ b/retrace/glstate_images.cpp
+@@ -1015,6 +1015,10 @@ getDrawBufferImage() {
+     if (context.ES) {
+         format = GL_RGBA;
+     }
++    else {
++        // Vivante driver does not support GL_RGB in openGL driver
++        format = GL_RGBA;
++    }
+ 
+     GLint channels = _gl_format_channels(format);
+     if (channels > 4) {
+@@ -1049,6 +1053,8 @@ getDrawBufferImage() {
+     {
+         // TODO: reset imaging state too
+         PixelPackState pps(context);
++        // FIXME! in case driver does not support full state
++        glGetError();
+         glReadPixels(0, 0, desc.width, desc.height, format, type, image->pixels);
+     }
+ 
+-- 
+2.7.4
+
diff --git a/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0014-MGS-469-GPU-hangs-when-retracing-OGLESParticles-on-m.patch b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0014-MGS-469-GPU-hangs-when-retracing-OGLESParticles-on-m.patch
new file mode 100644
index 0000000..1d2d7d6
--- /dev/null
+++ b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0014-MGS-469-GPU-hangs-when-retracing-OGLESParticles-on-m.patch
@@ -0,0 +1,28 @@
+From 172058a38ebe53080264ceebd4c10f18ea0b14fd Mon Sep 17 00:00:00 2001
+From: Yuchou Gan <yuchou.gan at nxp.com>
+Date: Thu, 19 Jan 2017 11:49:17 +0200
+Subject: [PATCH 14/31] MGS-469: GPU hangs when retracing OGLESParticles on
+ mx6sx
+
+---
+ retrace/retrace.py | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/retrace/retrace.py b/retrace/retrace.py
+index d506abc..164944e 100644
+--- a/retrace/retrace.py
++++ b/retrace/retrace.py
+@@ -465,7 +465,9 @@ class Retracer:
+         print '    if (retrace::verbosity >= 0) {'
+         print '        retrace::unsupported(call);'
+         print '    }'
+-        print '    return;'
++        # MGS-469: GPU hangs when retracing OGLESParticles on mx6sx
++        # Workaround: do not `return`
++        #print '    return;'
+ 
+     def extractArg(self, function, arg, arg_type, lvalue, rvalue):
+         ValueAllocator().visit(arg_type, lvalue, rvalue)
+-- 
+2.7.4
+
diff --git a/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0015-egl-define-egl-native-types-for-non-x11.patch b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0015-egl-define-egl-native-types-for-non-x11.patch
new file mode 100644
index 0000000..67c42ee
--- /dev/null
+++ b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0015-egl-define-egl-native-types-for-non-x11.patch
@@ -0,0 +1,36 @@
+From 1c1f29f549a121ed0a402c95044376457a882a35 Mon Sep 17 00:00:00 2001
+From: Yuchou Gan <yuchou.gan at nxp.com>
+Date: Thu, 19 Jan 2017 11:55:35 +0200
+Subject: [PATCH 15/31] egl: define egl native types for non-x11
+
+---
+ thirdparty/khronos/EGL/eglplatform.h | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/thirdparty/khronos/EGL/eglplatform.h b/thirdparty/khronos/EGL/eglplatform.h
+index 203f08c..ed189e2 100644
+--- a/thirdparty/khronos/EGL/eglplatform.h
++++ b/thirdparty/khronos/EGL/eglplatform.h
+@@ -111,6 +111,7 @@ typedef void *EGLNativeWindowType;
+ 
+ #elif defined(__unix__)
+ 
++#if defined(HAVE_X11)
+ /* X11 (tentative)  */
+ #include <X11/Xlib.h>
+ #include <X11/Xutil.h>
+@@ -118,6 +119,11 @@ typedef void *EGLNativeWindowType;
+ typedef Display *EGLNativeDisplayType;
+ typedef Pixmap   EGLNativePixmapType;
+ typedef Window   EGLNativeWindowType;
++#else
++typedef void *EGLNativeDisplayType;
++typedef void *EGLNativePixmapType;
++typedef void *EGLNativeWindowType;
++#endif
+ 
+ #else
+ #error "Platform not recognized"
+-- 
+2.7.4
+
diff --git a/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0016-don-t-recreate-the-EGL-surface-on-resize.patch b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0016-don-t-recreate-the-EGL-surface-on-resize.patch
new file mode 100644
index 0000000..129f598
--- /dev/null
+++ b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0016-don-t-recreate-the-EGL-surface-on-resize.patch
@@ -0,0 +1,32 @@
+From 2646cdaf6ae97d205251634196d23679e9b026bb Mon Sep 17 00:00:00 2001
+From: Adrian Negreanu <groleo at gmail.com>
+Date: Wed, 29 Mar 2017 14:39:17 +0300
+Subject: [PATCH 16/31] don't recreate the EGL surface on resize
+
+---
+ retrace/glws_egl_xlib.cpp | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/retrace/glws_egl_xlib.cpp b/retrace/glws_egl_xlib.cpp
+index f4c363c..e50e6dd 100644
+--- a/retrace/glws_egl_xlib.cpp
++++ b/retrace/glws_egl_xlib.cpp
+@@ -173,6 +173,7 @@ public:
+ 
+         eglWaitNative(EGL_CORE_NATIVE_ENGINE);
+ 
++#if 0
+         /*
+          * Some implementations won't update the backbuffer unless we recreate
+          * the EGL surface.
+@@ -193,6 +194,7 @@ public:
+ 
+         assert(eglWidth == width);
+         assert(eglHeight == height);
++#endif
+     }
+ 
+     void show(void) {
+-- 
+2.7.4
+
diff --git a/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0017-add-Image-getMD5.patch b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0017-add-Image-getMD5.patch
new file mode 100644
index 0000000..17ea445
--- /dev/null
+++ b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0017-add-Image-getMD5.patch
@@ -0,0 +1,69 @@
+From 6a49ded5002d9cc819a1810c16633b5c6e89881e Mon Sep 17 00:00:00 2001
+From: Adrian Negreanu <groleo at gmail.com>
+Date: Wed, 29 Mar 2017 14:41:42 +0300
+Subject: [PATCH 17/31] add Image::getMD5()
+
+---
+ image/image.hpp     |  3 +++
+ image/image_md5.cpp | 25 +++++++++++++++++++++++++
+ 2 files changed, 28 insertions(+)
+
+diff --git a/image/image.hpp b/image/image.hpp
+index e6f0d22..f128a34 100644
+--- a/image/image.hpp
++++ b/image/image.hpp
+@@ -114,6 +114,9 @@ public:
+     void
+     writeMD5(std::ostream &os) const;
+ 
++    char *
++    getMD5();
++
+     bool
+     writePNG(std::ostream &os, bool strip_alpha = false) const;
+ 
+diff --git a/image/image_md5.cpp b/image/image_md5.cpp
+index 85141e1..29a51b4 100644
+--- a/image/image_md5.cpp
++++ b/image/image_md5.cpp
+@@ -26,6 +26,7 @@
+ 
+ 
+ #include <fstream>
++#include <string.h>
+ #include "image.hpp"
+ 
+ #include "md5.h"
+@@ -60,5 +61,29 @@ Image::writeMD5(std::ostream &os) const {
+ }
+ 
+ 
++char *
++Image::getMD5() {
++    struct MD5Context md5c;
++    MD5Init(&md5c);
++    const unsigned char *row;
++    unsigned len = width*bytesPerPixel;
++    for (row = start(); row != end(); row += stride()) {
++        MD5Update(&md5c, (unsigned char *)row, len);
++    }
++    unsigned char signature[16];
++    MD5Final(signature, &md5c);
++
++    const char hex[] = "0123456789ABCDEF";
++    char csig[33];
++    for(int i = 0; i < sizeof signature; i++){
++        csig[2*i    ] = hex[signature[i] >> 4];
++        csig[2*i + 1] = hex[signature[i] & 0xf];
++    }
++    csig[32] = '\0';
++
++    return strdup(csig);
++}
++
++
+ } /* namespace image */
+ 
+-- 
+2.7.4
+
diff --git a/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0018-retrace-use-Image-getMD5-for-image-comparison.patch b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0018-retrace-use-Image-getMD5-for-image-comparison.patch
new file mode 100644
index 0000000..6abf051
--- /dev/null
+++ b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0018-retrace-use-Image-getMD5-for-image-comparison.patch
@@ -0,0 +1,175 @@
+From f1c0525bec534db50cb8020d9679ac2076573bb7 Mon Sep 17 00:00:00 2001
+From: Adrian Negreanu <groleo at gmail.com>
+Date: Wed, 29 Mar 2017 14:48:49 +0300
+Subject: [PATCH 18/31] retrace: use Image::getMD5() for image comparison
+
+---
+ retrace/retrace_main.cpp | 96 +++++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 95 insertions(+), 1 deletion(-)
+
+diff --git a/retrace/retrace_main.cpp b/retrace/retrace_main.cpp
+index ec49a16..72e0183 100644
+--- a/retrace/retrace_main.cpp
++++ b/retrace/retrace_main.cpp
+@@ -32,6 +32,7 @@
+ #include <getopt.h>
+ #ifndef _WIN32
+ #include <unistd.h> // for isatty()
++#include <fcntl.h>
+ #endif
+ 
+ #include "os_binary.hpp"
+@@ -60,6 +61,13 @@ static trace::CallSet snapshotFrequency;
+ static unsigned snapshotInterval = 0;
+ 
+ static unsigned dumpStateCallNo = ~0;
++static unsigned snapshotStart = 0;
++static unsigned snapshotStop = (unsigned)-1;
++static int compareImageFd = -1;
++
++
++static int checkMD5(char *md5, int framenr);
++
+ 
+ retrace::Retracer retracer;
+ 
+@@ -172,7 +180,13 @@ takeSnapshot(unsigned call_no) {
+                 src->writeRAW(std::cout);
+                 break;
+             case RAW_MD5:
+-                src->writeMD5(std::cout);
++                if(compareImageFd != -1) {
++                    char *md5 = src->getMD5();
++                    checkMD5(md5, snapshot_no);
++                }
++                else {
++                    src->writeMD5(std::cout);
++                }
+                 break;
+             default:
+                 assert(0);
+@@ -611,6 +625,9 @@ usage(const char *argv0) {
+         "      --snapshot-format=FMT       use (PNM, RGB, or MD5; default is PNM) when writing to stdout output\n"
+         "  -S, --snapshot=CALLSET  calls to snapshot (default is every frame)\n"
+         "      --snapshot-interval=N    specify a frame interval when generating snaphots (default is 0)\n"
++        "      --snapshot-start=N  start snapshot from frame N\n"
++        "      --snapshot-stop=N   stop snapshot before frame N\n"
++        "      --reference-dump=FILE    use a reference dump file to compare snapshot. Only MD5 is supported now.\n"
+         "  -v, --verbose           increase output verbosity\n"
+         "  -D, --dump-state=CALL   dump state at specific call no\n"
+         "      --dump-format=FORMAT dump state format (`json` or `ubjson`)\n"
+@@ -637,6 +654,9 @@ enum {
+     SINGLETHREAD_OPT,
+     SNAPSHOT_INTERVAL_OPT,
+     DUMP_FORMAT_OPT,
++    SNAPSHOT_STARTFRAME_OPT,
++    SNAPSHOT_STOPFRAME_OPT,
++    REFERENCE_DUMP_OPT,
+ };
+ 
+ const static char *
+@@ -669,6 +689,9 @@ longOptions[] = {
+     {"wait", no_argument, 0, 'w'},
+     {"loop", optional_argument, 0, LOOP_OPT},
+     {"singlethread", no_argument, 0, SINGLETHREAD_OPT},
++    {"snapshot-start", required_argument, 0, SNAPSHOT_STARTFRAME_OPT},
++    {"snapshot-stop", required_argument, 0, SNAPSHOT_STOPFRAME_OPT},
++    {"reference-dump", required_argument, 0, REFERENCE_DUMP_OPT},
+     {0, 0, 0, 0}
+ };
+ 
+@@ -678,6 +701,63 @@ static void exceptionCallback(void)
+     std::cerr << retrace::callNo << ": error: caught an unhandled exception\n";
+ }
+ 
++static int openReferenceDump(const char *file)
++{
++    compareImageFd = open(file, O_RDONLY);
++    if (compareImageFd == -1) {
++        std::cerr << "error: failed to open the reference dump file: " << file << std::endl;
++        return -1;
++    }
++    return 0;
++}
++
++// caller to free the return md5
++static char * getRefMD5(int fd, int frame)
++{
++    char buf[33];
++    // 33 chars per line (including '\n')
++    if(lseek(fd, frame * 33, SEEK_SET) == -1) {
++        std::cerr << "Failed to seek to frame " << frame << std::endl;
++        return NULL;
++    }
++    if(read(fd, buf, 32) != 32) {
++        std::cerr << "Failed to read 32 bytes\n";
++        return NULL;
++    }
++
++    buf[32] = 0;
++
++    return strdup(buf);
++}
++
++static int checkMD5(char *md5, int framenr)
++{
++    // read line #snapshot_no
++    char *md5ref = getRefMD5(compareImageFd, framenr);
++    int pass = 0;
++    if(md5 != NULL && md5ref != NULL && strcmp(md5, md5ref) == 0)
++    {
++        // pass
++        pass = 1;
++    }
++    else
++    {
++        // fail
++        pass = 0;
++    }
++    if(!pass) {
++        std::cerr << "Mismatch found for frame " << framenr
++            << ": reference " << (md5ref?md5ref:"(null)")
++            << ", but " << (md5?md5:"(null)") << " found\n";
++        exit(1); // no more test?
++    }
++    if(md5)
++        free(md5);
++    if(md5ref)
++        free(md5ref);
++
++    return 0;
++}
+ 
+ extern "C"
+ int main(int argc, char **argv)
+@@ -837,6 +917,17 @@ int main(int argc, char **argv)
+ 
+             retrace::profilingMemoryUsage = true;
+             break;
++        case SNAPSHOT_STARTFRAME_OPT:
++            snapshotStart = atoi(optarg);
++            break;
++        case SNAPSHOT_STOPFRAME_OPT:
++            snapshotStop = atoi(optarg);
++            break;
++        case REFERENCE_DUMP_OPT:
++            if (openReferenceDump(optarg)) {
++                return 1;
++            }
++            break;
+         default:
+             std::cerr << "error: unknown option " << opt << "\n";
+             usage(argv[0]);
+@@ -890,6 +981,9 @@ int main(int argc, char **argv)
+     // XXX: X often hangs on XCloseDisplay
+     //retrace::cleanUp();
+ 
++    if(compareImageFd != -1)
++        close(compareImageFd);
++
+ #ifdef _WIN32
+     if (mmRes == MMSYSERR_NOERROR) {
+         timeEndPeriod(tc.wPeriodMin);
+-- 
+2.7.4
+
diff --git a/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0019-egltrace-don-t-use-dlsym-on-aliased-functions.patch b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0019-egltrace-don-t-use-dlsym-on-aliased-functions.patch
new file mode 100644
index 0000000..ac21ce8
--- /dev/null
+++ b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0019-egltrace-don-t-use-dlsym-on-aliased-functions.patch
@@ -0,0 +1,91 @@
+From f5a450353de6bc8005e76b4babd9f7b4a13f796d Mon Sep 17 00:00:00 2001
+From: Yuchou Gan <yuchou.gan at nxp.com>
+Date: Thu, 19 Jan 2017 11:58:21 +0200
+Subject: [PATCH 19/31] egltrace: don't use dlsym on aliased functions
+
+Vivante driver uses function aliases for following OES/EXT:
+
+Extension API alias for GL_OES_texture_3D
+	glTexImage3DOES               glTexImage3D
+	glTexSubImage3DOES            glTexSubImage3D
+	glCopyTexSubImage3DOES        glCopyTexSubImage3D
+	glCompressedTexImage3DOES     glCompressedTexImage3D
+	glCompressedTexSubImage3DOES  glCompressedTexSubImage3D
+
+Extension API alias for GL_OES_get_program_binary
+	glGetProgramBinaryOES         glGetProgramBinary
+	glProgramBinaryOES            glProgramBinary
+
+Extension API alias for GL_OES_vertex_array_object
+	glBindVertexArrayOES          glBindVertexArray
+	glDeleteVertexArraysOES       glDeleteVertexArrays
+	glGenVertexArraysOES          glGenVertexArrays
+	glIsVertexArrayOES            glIsVertexArray
+
+Extension API alias for GL_OES_blend_minmax
+	glBlendEquationEXT            glBlendEquation
+---
+ wrappers/egltrace.py | 40 ++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 40 insertions(+)
+
+diff --git a/wrappers/egltrace.py b/wrappers/egltrace.py
+index 7d2d182..c7720bb 100644
+--- a/wrappers/egltrace.py
++++ b/wrappers/egltrace.py
+@@ -49,6 +49,9 @@ class EglTracer(GlTracer):
+     ]
+ 
+     def traceFunctionImplBody(self, function):
++        if function.name == 'eglGetProcAddress':
++            print '    procname = __get_alias_func_name(procname);'
++
+         GlTracer.traceFunctionImplBody(self, function)
+ 
+         if function.name == 'eglCreateContext':
+@@ -118,6 +121,43 @@ if __name__ == '__main__':
+     print '#include "glsize.hpp"'
+     print '#include "eglsize.hpp"'
+     print
++    print 'static const char *__get_alias_func_name(const char *origFunName)'
++    print '{'
++    print '    /* Vivante driver uses alias name for following OES/EXT functions, that means dlsym for thoese functions will fail */'
++    print '    static const char * __glExtProcAlias[][2] ='
++    print '    {'
++    print '        /* Extension API alias for GL_OES_texture_3D */'
++    print '        {"glTexImage3DOES",               "glTexImage3D"},'
++    print '        {"glTexSubImage3DOES",            "glTexSubImage3D"},'
++    print '        {"glCopyTexSubImage3DOES",        "glCopyTexSubImage3D"},'
++    print '        {"glCompressedTexImage3DOES",     "glCompressedTexImage3D"},'
++    print '        {"glCompressedTexSubImage3DOES",  "glCompressedTexSubImage3D"},'
++    print
++    print '        /* Extension API alias for GL_OES_get_program_binary */'
++    print '        {"glGetProgramBinaryOES",         "glGetProgramBinary"},'
++    print '        {"glProgramBinaryOES",            "glProgramBinary"},'
++    print
++    print '        /* Extension API alias for GL_OES_vertex_array_object */'
++    print '        {"glBindVertexArrayOES",          "glBindVertexArray"},'
++    print '        {"glDeleteVertexArraysOES",       "glDeleteVertexArrays"},'
++    print '        {"glGenVertexArraysOES",          "glGenVertexArrays"},'
++    print '        {"glIsVertexArrayOES",            "glIsVertexArray"},'
++    print
++    print '        /* Extension API alias for GL_OES_blend_minmax */'
++    print '        {"glBlendEquationEXT",            "glBlendEquation"}'
++    print '    };'
++    print
++    print '    int count = sizeof(__glExtProcAlias) / sizeof(__glExtProcAlias[0]);'
++    print '    int i;'
++    print
++    print '    for(i=0; i<count; i++)'
++    print '    {'
++    print '        if(strcmp(__glExtProcAlias[i][0], origFunName) == 0)'
++    print '            return __glExtProcAlias[i][1];'
++    print '    }'
++    print
++    print '    return origFunName;'
++    print '}'
+     
+     module = Module()
+     module.mergeModule(eglapi)
+-- 
+2.7.4
+
diff --git a/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0020-egl-glx-trace-add-ApiTraceEnabled.patch b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0020-egl-glx-trace-add-ApiTraceEnabled.patch
new file mode 100644
index 0000000..58d9022
--- /dev/null
+++ b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0020-egl-glx-trace-add-ApiTraceEnabled.patch
@@ -0,0 +1,79 @@
+From b0b1ee6963cb87f7465c45fce756baa7e3ff6883 Mon Sep 17 00:00:00 2001
+From: Adrian Negreanu <groleo at gmail.com>
+Date: Wed, 19 Apr 2017 16:28:55 +0300
+Subject: [PATCH 20/31] (egl|glx)trace: add ApiTraceEnabled
+
+This is a dummy API to let the GPU driver know that we are in
+apitrace.
+---
+ wrappers/egltrace.py      | 11 +++++++++++
+ wrappers/egltrace.version |  1 +
+ wrappers/glxtrace.py      | 11 +++++++++++
+ wrappers/glxtrace.version |  1 +
+ 4 files changed, 24 insertions(+)
+
+diff --git a/wrappers/egltrace.py b/wrappers/egltrace.py
+index c7720bb..6d032eb 100644
+--- a/wrappers/egltrace.py
++++ b/wrappers/egltrace.py
+@@ -294,3 +294,14 @@ void APIENTRY glWeightPointerOESBounds(GLint size, GLenum type, GLsizei stride,
+ 
+ 
+ '''
++    print r'''
++/*
++ * This is a dummy API to let the GPU driver know that we are in apitrace
++ */
++extern "C" PUBLIC
++void APIENTRY ApiTraceEnabled(void) {
++    // a dummy function
++    os::log("Dummy API function\n");
++}
++
++'''
+diff --git a/wrappers/egltrace.version b/wrappers/egltrace.version
+index 0e7e62b..4009857 100644
+--- a/wrappers/egltrace.version
++++ b/wrappers/egltrace.version
+@@ -5,6 +5,7 @@
+         egl[A-Z]*;
+         gl[A-Z]*;
+         dlopen;
++        ApiTraceEnabled;
+     local:
+         *;
+ };
+diff --git a/wrappers/glxtrace.py b/wrappers/glxtrace.py
+index e9c43a9..d9ffe56 100644
+--- a/wrappers/glxtrace.py
++++ b/wrappers/glxtrace.py
+@@ -227,3 +227,14 @@ void * dlopen(const char *filename, int flag)
+ 
+ 
+ '''
++    print r'''
++/*
++ * This is a dummy API to let the GPU driver know that we are in apitrace
++ */
++extern "C" PUBLIC
++void APIENTRY ApiTraceEnabled(void) {
++    // a dummy function
++    os::log("Dummy API function\n");
++}
++
++'''
+diff --git a/wrappers/glxtrace.version b/wrappers/glxtrace.version
+index 7d7a162..7402d6f 100644
+--- a/wrappers/glxtrace.version
++++ b/wrappers/glxtrace.version
+@@ -4,6 +4,7 @@
+         _fini;
+         gl[A-Z]*;
+         dlopen;
++        ApiTraceEnabled;
+     local:
+         *;
+ };
+-- 
+2.7.4
+
diff --git a/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0021-LocalWriter-make-a-writer-ignorable.patch b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0021-LocalWriter-make-a-writer-ignorable.patch
new file mode 100644
index 0000000..5cbbe90
--- /dev/null
+++ b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0021-LocalWriter-make-a-writer-ignorable.patch
@@ -0,0 +1,101 @@
+From 60ed9aa18ddd36f5e9fa3169245df2091244dcb1 Mon Sep 17 00:00:00 2001
+From: Adrian Negreanu <groleo at gmail.com>
+Date: Wed, 19 Apr 2017 17:52:04 +0300
+Subject: [PATCH 21/31] LocalWriter: make a writer ignorable
+
+---
+ common/trace_writer_local.cpp | 34 ++++++++++++++++++++++++++++++++++
+ common/trace_writer_local.hpp | 25 +++++++++++++++++++++++++
+ 2 files changed, 59 insertions(+)
+
+diff --git a/common/trace_writer_local.cpp b/common/trace_writer_local.cpp
+index 41f39c8..17b6328 100644
+--- a/common/trace_writer_local.cpp
++++ b/common/trace_writer_local.cpp
+@@ -157,6 +157,9 @@ static uintptr_t next_thread_num = 1;
+ static OS_THREAD_SPECIFIC(uintptr_t)
+ thread_num;
+ 
++static OS_THREAD_SPECIFIC(uint32_t)
++ignored_num;
++
+ void LocalWriter::checkProcessId(void) {
+     if (m_file &&
+         os::getCurrentProcessId() != pid) {
+@@ -244,6 +247,37 @@ void LocalWriter::flush(void) {
+ }
+ 
+ 
++bool LocalWriter::isIgnored(void) {
++    mutex.lock();
++    if (0==ignored_num){
++        mutex.unlock();
++        return false;
++    } else {
++        mutex.unlock();
++        return true;
++    }
++}
++
++void LocalWriter::beginIgnore(void) {
++    mutex.lock();
++    ++ignored_num;
++}
++
++void LocalWriter::endIgnore(void) {
++    mutex.unlock();
++}
++
++void LocalWriter::beginTrace(void) {
++    mutex.lock();
++    --ignored_num;
++}
++
++void LocalWriter::endTrace(void) {
++    mutex.unlock();
++}
++
++
++
+ LocalWriter localWriter;
+ 
+ 
+diff --git a/common/trace_writer_local.hpp b/common/trace_writer_local.hpp
+index 5d55bd9..ed27dbb 100644
+--- a/common/trace_writer_local.hpp
++++ b/common/trace_writer_local.hpp
+@@ -108,6 +108,31 @@ namespace trace {
+         void endLeave(void);
+ 
+         void flush(void);
++
++        /**
++         * Check ingore state
++         */
++        bool isIgnored(void);
++
++        /**
++         * It will stop the trace apicall.
++         */
++        void beginIgnore(void);
++
++        /**
++         * It will release mutex.
++         */
++        void endIgnore(void);
++
++        /**
++         * It will resume the trace apicall.
++         */
++        void beginTrace(void);
++
++        /**
++         * It will release mutex.
++         */
++        void endTrace(void);
+     };
+ 
+     /**
+-- 
+2.7.4
+
diff --git a/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0022-MGS-309-ccc-retrace-tutorial3-is-different-with-trac.patch b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0022-MGS-309-ccc-retrace-tutorial3-is-different-with-trac.patch
new file mode 100644
index 0000000..1f62814
--- /dev/null
+++ b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0022-MGS-309-ccc-retrace-tutorial3-is-different-with-trac.patch
@@ -0,0 +1,82 @@
+From 9131ba8b2484308ee3f5083e085ff2cf976bc4c1 Mon Sep 17 00:00:00 2001
+From: Adrian Negreanu <groleo at gmail.com>
+Date: Wed, 19 Apr 2017 17:58:14 +0300
+Subject: [PATCH 22/31] MGS-309 [#ccc] retrace "tutorial3" is different with
+ trace it.
+
+glMultiDrawElementsEXT is implemented by calling glDrawElements.
+
+Since apitrace traces both glMultiDrawElementsEXT and glDrawElements, this
+will mess up the trace.
+
+This patch will only trace glMultiDrawElementsEXT without the nested
+glDrawElements calls.
+---
+ wrappers/gltrace.py |  6 ++++++
+ wrappers/trace.py   | 12 ++++++++++++
+ 2 files changed, 18 insertions(+)
+
+diff --git a/wrappers/gltrace.py b/wrappers/gltrace.py
+index 769f2e3..6f96572 100644
+--- a/wrappers/gltrace.py
++++ b/wrappers/gltrace.py
+@@ -404,6 +404,7 @@ class GlTracer(Tracer):
+ 
+     # XXX: We currently ignore the gl*Draw*ElementArray* functions
+     draw_function_regex = re.compile(r'^gl([A-Z][a-z]+)*Draw(Range)?(Arrays|Elements)([A-Z][a-zA-Z]*)?$' )
++    multi_draw_function_regex = re.compile(r'^glMultiDraw(Arrays|Elements)([A-Z][a-zA-Z]*)?$' )
+ 
+     interleaved_formats = [
+          'GL_V2F',
+@@ -503,6 +504,11 @@ class GlTracer(Tracer):
+ 
+         # ... to the draw calls
+         if self.draw_function_regex.match(function.name):
++            if not self.multi_draw_function_regex.match(function.name):
++                print '    if (trace::localWriter.isIgnored()) {'
++                self.invokeFunction(function)
++                print '        return;'
++                print '    }'
+             print '    if (_need_user_arrays()) {'
+             if 'Indirect' in function.name:
+                 print r'        os::log("apitrace: warning: %s: indirect user arrays not supported\n");' % (function.name,)
+diff --git a/wrappers/trace.py b/wrappers/trace.py
+index cb51024..efb2fd5 100644
+--- a/wrappers/trace.py
++++ b/wrappers/trace.py
+@@ -35,6 +35,7 @@ import itertools
+ 
+ import specs.stdapi as stdapi
+ 
++import re
+ 
+ def getWrapperInterfaceName(interface):
+     return "Wrap" + interface.expr
+@@ -560,13 +561,24 @@ class Tracer:
+         print
+ 
+     def traceFunctionImplBody(self, function):
++        multi_draw_function_regex = re.compile(r'^glMultiDraw(Arrays|Elements)([A-Z][a-zA-Z]*)?$' )
+         if not function.internal:
+             print '    unsigned _call = trace::localWriter.beginEnter(&_%s_sig);' % (function.name,)
+             for arg in function.args:
+                 if not arg.output:
+                     self.serializeArg(function, arg)
+             print '    trace::localWriter.endEnter();'
++
++        if self.multi_draw_function_regex.match(function.name):
++            print '    trace::localWriter.beginIgnore();'
++            print '    trace::localWriter.endIgnore();'
++
+         self.invokeFunction(function)
++
++        if self.multi_draw_function_regex.match(function.name):
++            print '    trace::localWriter.beginTrace();'
++            print '    trace::localWriter.endTrace();'
++
+         if not function.internal:
+             print '    trace::localWriter.beginLeave(_call);'
+             print '    if (%s) {' % self.wasFunctionSuccessful(function)
+-- 
+2.7.4
+
diff --git a/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0023-add-support-for-Vivante-extensions.patch b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0023-add-support-for-Vivante-extensions.patch
new file mode 100644
index 0000000..52a2996
--- /dev/null
+++ b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0023-add-support-for-Vivante-extensions.patch
@@ -0,0 +1,444 @@
+From 32fa35eca3f5f1fa9014a3cc2d29cecaa01dbe5d Mon Sep 17 00:00:00 2001
+From: Adrian Negreanu <groleo at gmail.com>
+Date: Thu, 20 Apr 2017 10:15:29 +0300
+Subject: [PATCH 23/31] add support for Vivante extensions
+
+glTexDirectVIVMap
+glTexDirectMapVIV
+glTexDirectTiledMapVIV
+
+Note: this adds a dependency on the G2D libraries.
+---
+ CMakeLists.txt          |  11 ++++
+ cmake/FindVivante.cmake |  29 ++++++++++
+ retrace/CMakeLists.txt  |   5 +-
+ retrace/glretrace.py    | 142 ++++++++++++++++++++++++++++++++++++++++++++++++
+ specs/glapi.py          |   7 +++
+ wrappers/egltrace.py    | 121 ++++++++++++++++++++++++++++++++++++++++-
+ 6 files changed, 313 insertions(+), 2 deletions(-)
+ create mode 100644 cmake/FindVivante.cmake
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index ce5fd4c..5efc888 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -44,6 +44,8 @@ option (ENABLE_WAFFLE "Enable WAFFLE support." OFF)
+ 
+ option (ENABLE_FRAME_POINTER "Disable frame pointer omission" ON)
+ 
++option (ENABLE_VIVANTE "Enable Vivante support." OFF)
++
+ # Proprietary Linux games often ship their own libraries (zlib, libstdc++,
+ # etc.) in order to ship a single set of binaries across multiple
+ # distributions.  Given that apitrace wrapper modules will be loaded into those
+@@ -159,6 +161,15 @@ if (ENABLE_EGL AND ENABLE_WAFFLE)
+     find_package (Waffle REQUIRED)
+ endif ()
+ 
++if (ENABLE_VIVANTE)
++    find_package (Vivante)
++    if (Vivante_FOUND)
++        add_definitions (-DHAVE_VIVANTE_G2D)
++    else()
++        message (FATAL_ERROR "Vivante requested but not found.")
++    endif()
++endif ()
++
+ 
+ ##############################################################################
+ # Set global build options
+diff --git a/cmake/FindVivante.cmake b/cmake/FindVivante.cmake
+new file mode 100644
+index 0000000..6ec1352
+--- /dev/null
++++ b/cmake/FindVivante.cmake
+@@ -0,0 +1,29 @@
++# - Vivante headers and libraries
++#set (Vivante_INC_SEARCH_PATH "usr/include")
++find_path (Vivante_G2D_INCLUDE_DIR g2d.h
++	PATHS ${Vivante_INC_SEARCH_PATH}
++	DOC "The directory where gd2.h resides"
++	)
++
++find_library (Vivante_G2D_LIBRARY libg2d.so
++	PATHS ${Vivante_LIB_SEARCH_PATH}
++	DOC "The directory where libg2d resides"
++	)
++find_library (Vivante_VDK_LIBRARY libVDK.so
++	PATHS ${Vivante_LIB_SEARCH_PATH}
++	DOC "The directory where libVDK resides"
++	)
++
++if (Vivante_G2D_INCLUDE_DIR AND Vivante_G2D_LIBRARY AND Vivante_VDK_LIBRARY)
++	set (Vivante_FOUND 1)
++endif ()
++
++mark_as_advanced (
++	Vivante_G2D_INCLUDE_DIR
++	Vivante_G2D_LIBRARY
++	Vivante_VDK_LIBRARY
++)
++
++mark_as_advanced (
++	Vivante_FOUND
++)
+diff --git a/retrace/CMakeLists.txt b/retrace/CMakeLists.txt
+index 9973e2c..fb8e299 100644
+--- a/retrace/CMakeLists.txt
++++ b/retrace/CMakeLists.txt
+@@ -131,6 +131,7 @@ if (WIN32 OR APPLE OR X11_FOUND)
+             # http://stackoverflow.com/questions/2702628/gdb-cannot-find-new-threads-generic-error
+             ${CMAKE_THREAD_LIBS_INIT}
+             ${CMAKE_DL_LIBS}
++            ${Vivante_G2D_LIBRARY}
+         )
+     endif ()
+ 
+@@ -154,6 +155,7 @@ if (ENABLE_EGL AND X11_FOUND AND NOT WIN32 AND NOT APPLE AND NOT ENABLE_WAFFLE)
+         ${X11_X11_LIB}
+         ${CMAKE_THREAD_LIBS_INIT}
+         ${CMAKE_DL_LIBS}
++        ${Vivante_G2D_LIBRARY}
+     )
+     install (TARGETS eglretrace RUNTIME DESTINATION bin) 
+ endif ()
+@@ -173,7 +175,8 @@ if (Vivante_FOUND AND ENABLE_EGL AND NOT X11_FOUND AND NOT WIN32 AND NOT APPLE A
+         glproc_egl
+         ${CMAKE_THREAD_LIBS_INIT}
+         ${CMAKE_DL_LIBS}
+-        VDK
++        ${Vivante_G2D_LIBRARY}
++        ${Vivante_VDK_LIBRARY}
+     )
+ 
+     if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+diff --git a/retrace/glretrace.py b/retrace/glretrace.py
+index db351e8..6b5608b 100644
+--- a/retrace/glretrace.py
++++ b/retrace/glretrace.py
+@@ -174,6 +174,59 @@ class GlRetracer(Retracer):
+ 
+ 
+     def invokeFunction(self, function):
++        if function.name == "glTexDirectVIVMap" or function.name == "glTexDirectMapVIV" or function.name == "glTexDirectTiledMapVIV":
++            print '#if defined(HAVE_VIVANTE_G2D)'
++            print '    GLint tex;'
++            print '    glGetIntegerv(GL_TEXTURE_BINDING_2D, &tex);'
++            print '    int32_t size = 0;'
++            print '    switch(format){'
++            print '    case GL_VIV_YV12:'
++            print '    case GL_VIV_I420:'
++            print '    case GL_VIV_NV12:'
++            print '    case GL_VIV_NV21:'
++            print '        size=width * height * 3 / 2;'
++            print '        break;'
++            print '    case GL_RGBA:'
++            print '    case GL_BGRA_EXT:'
++            print '        size=width * height * 4;'
++            print '        break;'
++            print '    case GL_RGB:'
++            print '        size=width * height *3;'
++            print '        break;'
++            print '    case GL_VIV_YUY2:'
++            print '    case GL_VIV_UYVY:'
++            print '    case GL_RGB565_OES:'
++            print '        size=width * height *2;'
++            print '        break;'
++            print '    default:'
++            print '        break;'
++            print '    }'
++            print '    if(tex != 0)'
++            print '    {'
++            print '        TEXDIRECTVIVDATA &data = _directTextureDataMap[tex];'
++            print '        if(data.privateData == 0) // new entry'
++            print '        {'
++            print '            data.privateData = alloc_dma_buffer(size, &data.logical, &data.physical);'
++            print '            data.index=Logical[0];'
++            print '            data.size=size;'
++            print '            retrace::addRegion(call,data.index,(void*)data.logical,size);'
++            print '        }'
++            print '        else // already have one; check size and index'
++            print '        {'
++            print '            if((size!=data.size)||(Logical[0]!=data.index))'
++            print '            {'
++            print '                retrace::delRegionByPointer((void*)data.logical);'
++            print '                free_dma_buffer(data.privateData);'
++            print '                data.privateData = alloc_dma_buffer(size, &data.logical, &data.physical);'
++            print '                data.index=Logical[0];'
++            print '                data.size=size;'
++            print '                retrace::addRegion(call,data.index,(void*)data.logical,size);'
++            print '            }'
++            print '        }'
++            print '        *Logical = data.logical;'
++            print '        *Physical = data.physical;'
++            print '    }'
++            print '#endif /* HAVE_VIVANTE_G2D */'
+         # Infer the drawable size from GL calls
+         if function.name == "glViewport":
+             print '    glretrace::updateDrawable(x + width, y + height);'
+@@ -356,6 +409,54 @@ class GlRetracer(Retracer):
+             print '        currentContext->insideBeginEnd = true;'
+             print '    }'
+ 
++        if function.name == "glTexDirectVIV":
++            print '#if defined(HAVE_VIVANTE_G2D)'
++            print '    int32_t ysize = 0;'
++            print '    int32_t usize = 0;'
++            print '    int32_t vsize = 0;'
++            print '    switch(format){'
++            print '    case GL_VIV_YV12:'
++            print '    case GL_VIV_I420:'
++            print '        ysize=width * height;'
++            print '        usize=ysize/4;'
++            print '        vsize=usize;'
++            print '        break;'
++            print '    case GL_VIV_NV12:'
++            print '    case GL_VIV_NV21:'
++            print '        ysize=width * height;'
++            print '        usize=ysize/2;'
++            print '        vsize=0;'
++            print '        break;'
++            print '    case GL_RGBA:'
++            print '    case GL_BGRA_EXT:'
++            print '        ysize=width * height *4;'
++            print '        usize=0;'
++            print '        vsize=0;'
++            print '        break;'
++            print '    case GL_RGB:'
++            print '        ysize=width * height *3;'
++            print '        usize=0;'
++            print '        vsize=0;'
++            print '        break;'
++            print '    case GL_VIV_YUY2:'
++            print '    case GL_VIV_UYVY:'
++            print '    case GL_RGB565_OES:'
++            print '        ysize=width * height *2;'
++            print '        usize=0;'
++            print '        vsize=0;'
++            print '        break;'
++            print '    default:'
++            print '        break;'
++            print '    }'
++            print '    const trace::Array * arrayGLvoid = (call.arg(4)).toArray();'
++            print '    if(ysize > 0)'
++            print '        retrace::addRegion(call,(*arrayGLvoid->values[0]).toUInt(),(GLvoid*)pixels[0], ysize);'
++            print '    if(usize > 0)'
++            print '        retrace::addRegion(call,(*arrayGLvoid->values[1]).toUInt(),(GLvoid*)pixels[1], usize);'
++            print '    if(vsize > 0)'
++            print '        retrace::addRegion(call,(*arrayGLvoid->values[2]).toUInt(),(GLvoid*)pixels[2], vsize);'
++            print '#endif /* HAVE_VIVANTE_G2D */'
++
+         print r'    if (currentContext && !currentContext->insideList && !currentContext->insideBeginEnd && retrace::profiling) {'
+         if profileDraw:
+             print r'        glretrace::endProfile(call, true);'
+@@ -545,6 +646,47 @@ _getActiveProgram(void);
+ static void
+ _validateActiveProgram(trace::Call &call);
+ 
++#if defined(HAVE_VIVANTE_G2D)
++
++#define GL_VIV_YV12                        0x8FC0
++#define GL_VIV_NV12                        0x8FC1
++#define GL_VIV_YUY2                        0x8FC2
++#define GL_VIV_UYVY                        0x8FC3
++#define GL_VIV_NV21                        0x8FC4
++#define GL_VIV_I420                        0x8FC5
++
++typedef struct TexDirectVivData
++{
++    GLuint   logical; // used for glTexDirectVIVMap/glTexDirectMapVIV/glTexDirectTiledMapVIV
++    GLuint   physical;
++    GLuint   index;
++    uint32_t size;
++    void *privateData; // used to allocate buffer
++}TEXDIRECTVIVDATA;
++
++static std::map<GLint, TEXDIRECTVIVDATA> _directTextureDataMap;
++
++#include <g2d.h>
++
++static void * alloc_dma_buffer(int size, unsigned int *logical, unsigned int *physical)
++{
++    struct g2d_buf *buf = g2d_alloc(size, 0);
++    if(buf != NULL)
++    {
++        *logical = (unsigned int)buf->buf_vaddr;
++        *physical = (unsigned int)buf->buf_paddr ;
++    }
++    return buf;
++}
++
++static void free_dma_buffer(void *buf)
++{
++    if(buf != NULL)
++        g2d_free((g2d_buf *)buf);
++}
++
++#endif /* HAVE_VIVANTE_G2D */
++
+ '''
+     api = stdapi.API()
+     api.addModule(glapi.glapi)
+diff --git a/specs/glapi.py b/specs/glapi.py
+index d56d7fa..b0c30b3 100644
+--- a/specs/glapi.py
++++ b/specs/glapi.py
+@@ -3588,4 +3588,11 @@ glapi.addFunctions([
+     # GL_WIN_swap_hint
+     GlFunction(Void, "glAddSwapHintRectWIN", [(GLint, "x"), (GLint, "y"), (GLsizei, "width"), (GLsizei, "height")]),
+ 
++    # Vivante extension
++    GlFunction(Void, "glTexDirectVIV", [(GLenum, "target"), (GLsizei, "width"), (GLsizei, "height"), (GLenum, "format"), Out(Array(GLuint, 3), "pixels")]),
++    GlFunction(Void, "glTexDirectVIVMap", [(GLenum, "target"), (GLsizei, "width"), (GLsizei, "height"), (GLenum, "format"),      (Pointer(GLuint), "Logical"), (Pointer(Const(GLuint)), "Physical")]),
++    GlFunction(Void, "glTexDirectMapVIV", [(GLenum, "target"), (GLsizei, "width"), (GLsizei, "height"), (GLenum, "format"),       (Pointer(GLuint), "Logical"), (Pointer(Const(GLuint)), "Physical")]),
++    GlFunction(Void, "glTexDirectTiledMapVIV", [(GLenum, "target"), (GLsizei, "width"), (GLsizei, "height"), (GLenum, "format"), (Pointer(GLuint), "Logical"), (Pointer(Const(GLuint)), "Physical")]),
++    GlFunction(Void, "glTexDirectInvalidateVIV", [(GLenum, "target")]),
++
+ ])
+diff --git a/wrappers/egltrace.py b/wrappers/egltrace.py
+index 6d032eb..683f562 100644
+--- a/wrappers/egltrace.py
++++ b/wrappers/egltrace.py
+@@ -49,11 +49,109 @@ class EglTracer(GlTracer):
+     ]
+ 
+     def traceFunctionImplBody(self, function):
++        if function.name == 'glTexDirectMapVIV':
++            print '    // prevent loop call'
++            print '    glTexDirectVIVMap(target, width, height, format, Logical, Physical);'
++            return
++
++        if function.name == 'glTexDirectInvalidateVIV':
++            print '    // get current texture'
++            print '    GLint tex = 0;'
++            print '    int32_t size = 0;'
++            print '    int32_t ysize = 0;'
++            print '    int32_t usize = 0;'
++            print '    int32_t vsize = 0;'
++            print '    _glGetIntegerv(GL_TEXTURE_BINDING_2D, &tex);'
++            print '    if(tex == 0)'
++            print '    {'
++            print '        return;'
++            print '    }'
++            print '    TEXDIRECTVIVDATA &data = _directTextureDataMap[tex];'
++            print '    switch(data.format){'
++            print '    case GL_VIV_YV12:'
++            print '    case GL_VIV_I420:'
++            print '        ysize=data.width * data.height;'
++            print '        usize=ysize/4;'
++            print '        vsize=usize;'
++            print '        break;'
++            print '    case GL_VIV_NV12:'
++            print '    case GL_VIV_NV21:'
++            print '        ysize=data.width * data.height;'
++            print '        usize=ysize/2;'
++            print '        vsize=0;'
++            print '        break;'
++            print '    case GL_RGBA:'
++            print '    case GL_BGRA_EXT:'
++            print '        ysize=data.width * data.height *4;'
++            print '        usize=0;'
++            print '        vsize=0;'
++            print '        break;'
++            print '    case GL_RGB:'
++            print '        ysize=data.width * data.height *3;'
++            print '        usize=0;'
++            print '        vsize=0;'
++            print '        break;'
++            print '    case GL_VIV_YUY2:'
++            print '    case GL_VIV_UYVY:'
++            print '    case GL_RGB565_OES:'
++            print '        ysize=data.width * data.height *2;'
++            print '        usize=0;'
++            print '        vsize=0;'
++            print '        break;'
++            print '    default:'
++            print '        return;'
++            print '    }'
++            print '    if (NULL==(GLvoid*)data.logical) {'
++            print '        if (ysize > 0) {'
++            self.emit_memcpy('(GLvoid*)data.planes[0]', 'ysize')
++            print '         }'
++            print '        if (usize > 0) {'
++            self.emit_memcpy('(GLvoid*)data.planes[1]', 'usize')
++            print '         }'
++            print '        if (vsize > 0) {'
++            self.emit_memcpy('(GLvoid*)data.planes[2]', 'vsize')
++            print '         }'
++            print '    } else {'
++            print '        size = ysize + usize + vsize;'
++            print '        if (size > 0) {'
++            self.emit_memcpy('(GLvoid*)data.logical', 'size')
++            print '         }'
++            print '    }'
++
+         if function.name == 'eglGetProcAddress':
+             print '    procname = __get_alias_func_name(procname);'
+ 
+         GlTracer.traceFunctionImplBody(self, function)
+ 
++        if function.name == 'glTexDirectVIV':
++            print '    // get current texture'
++            print '    GLint tex = 0;'
++            print '    _glGetIntegerv(GL_TEXTURE_BINDING_2D, &tex);'
++            print '    if(tex != 0)'
++            print '    {'
++            print '        TEXDIRECTVIVDATA &data = _directTextureDataMap[tex];'
++            print '        data.width = width;'
++            print '        data.height = height;'
++            print '        data.format = format;'
++            print '        data.planes[0] = pixels[0];'
++            print '        data.planes[1] = pixels[1];'
++            print '        data.planes[2] = pixels[2];'
++            print '    }'
++
++        if function.name == 'glTexDirectVIVMap' or function.name == 'glTexDirectTiledMapVIV':
++            print '    // get current texture'
++            print '    GLint tex = 0;'
++            print '    _glGetIntegerv(GL_TEXTURE_BINDING_2D, &tex);'
++            print '    if(tex != 0)'
++            print '    {'
++            print '        TEXDIRECTVIVDATA &data = _directTextureDataMap[tex];'
++            print '        data.width = width;'
++            print '        data.height = height;'
++            print '        data.format = format;'
++            print '        data.logical = *Logical; // Logical != NULL'
++            print '        data.physical = *Physical;'
++            print '    }'
++
+         if function.name == 'eglCreateContext':
+             print '    if (_result != EGL_NO_CONTEXT)'
+             print '        gltrace::createContext((uintptr_t)_result);'
+@@ -158,7 +256,28 @@ if __name__ == '__main__':
+     print
+     print '    return origFunName;'
+     print '}'
+-    
++
++    print
++    print 'typedef struct TexDirectVivData'
++    print '{'
++    print '    int width;'
++    print '    int height;'
++    print '    GLenum format;'
++    print '    GLuint planes[3]; // used for glTexDirectVIV'
++    print '    GLuint logical; // used for glTexDirectVIVMap/glTexDirectMapVIV/glTexDirectTiledMapVIV'
++    print '    GLuint physical;'
++    print '}TEXDIRECTVIVDATA;'
++    print
++    print 'static std::map<GLint, TEXDIRECTVIVDATA> _directTextureDataMap;'
++    print
++    print '#define GL_VIV_YV12                        0x8FC0'
++    print '#define GL_VIV_NV12                        0x8FC1'
++    print '#define GL_VIV_YUY2                        0x8FC2'
++    print '#define GL_VIV_UYVY                        0x8FC3'
++    print '#define GL_VIV_NV21                        0x8FC4'
++    print '#define GL_VIV_I420                        0x8FC5'
++    print
++
+     module = Module()
+     module.mergeModule(eglapi)
+     module.mergeModule(glapi)
+-- 
+2.7.4
+
diff --git a/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0024-MGS-470-ccc-cannot-trace-mesa-demos-vertexrate.patch b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0024-MGS-470-ccc-cannot-trace-mesa-demos-vertexrate.patch
new file mode 100644
index 0000000..42db8e2
--- /dev/null
+++ b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0024-MGS-470-ccc-cannot-trace-mesa-demos-vertexrate.patch
@@ -0,0 +1,34 @@
+From 45925668371f89ac0dfffe59afac77e87588fc1e Mon Sep 17 00:00:00 2001
+From: Yang Dong <b56112 at freescale.com>
+Date: Thu, 20 Apr 2017 10:27:12 +0300
+Subject: [PATCH 24/31] MGS-470 [#ccc] cannot trace mesa-demos/vertexrate
+
+Root cause: glxGetCurrentDisplay goes into a infinite loop.
+
+Solution: Before calling _glxGetCurrentDisplay, check the value of it.
+If _glxGetCurrentDisplay reference glxGetCurrentDisplay, redirect it to proper lib.
+
+Signed-off-by: Yang Dong <b56112 at freescale.com>
+---
+ wrappers/glxtrace.py | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/wrappers/glxtrace.py b/wrappers/glxtrace.py
+index d9ffe56..e2d0fc4 100644
+--- a/wrappers/glxtrace.py
++++ b/wrappers/glxtrace.py
+@@ -66,6 +66,11 @@ class GlxTracer(GlTracer):
+         if function.name in self.destroyContextFunctionNames:
+             print '    gltrace::releaseContext((uintptr_t)ctx);'
+ 
++        if function.name == 'glXGetCurrentDisplay':
++            print '    if(_glXGetCurrentDisplay == &glXGetCurrentDisplay ){'
++            print '        _glXGetCurrentDisplay = (PFN_GLXGETCURRENTDISPLAY)_getPublicProcAddress("glXGetCurrentDisplay");'
++            print '    }'
++
+         GlTracer.traceFunctionImplBody(self, function)
+ 
+         if function.name in self.createContextFunctionNames:
+-- 
+2.7.4
+
diff --git a/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0025-MGS-1271-ccc-disable-X-debug-function.patch b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0025-MGS-1271-ccc-disable-X-debug-function.patch
new file mode 100644
index 0000000..8194084
--- /dev/null
+++ b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0025-MGS-1271-ccc-disable-X-debug-function.patch
@@ -0,0 +1,30 @@
+From a36e8a1a3eb0fdb1217bc17d8c28d5b528855a87 Mon Sep 17 00:00:00 2001
+From: Yang Dong <b56112 at freescale.com>
+Date: Fri, 20 Nov 2015 02:23:50 +0800
+Subject: [PATCH 25/31] MGS-1271 [#ccc] disable X debug function
+
+Accoring to the yocto cmake file, NDEBUG is not defined.
+So disable X debug to make apitrace's replay function work.
+
+Date: Nov 19, 2015
+Signed-off-by: Yang Dong <b56112 at freescale.com>
+---
+ retrace/glws_xlib.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/retrace/glws_xlib.cpp b/retrace/glws_xlib.cpp
+index 56bb043..6e13124 100644
+--- a/retrace/glws_xlib.cpp
++++ b/retrace/glws_xlib.cpp
+@@ -111,7 +111,7 @@ void
+ initX(void)
+ {
+ #ifndef NDEBUG
+-    _Xdebug = 1;
++    _Xdebug = 0;
+ #endif
+ 
+     XInitThreads();
+-- 
+2.7.4
+
diff --git a/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0026-MGS-1721-ccc-fix-broken-build-on-AArch64.patch b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0026-MGS-1721-ccc-fix-broken-build-on-AArch64.patch
new file mode 100644
index 0000000..0549278
--- /dev/null
+++ b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0026-MGS-1721-ccc-fix-broken-build-on-AArch64.patch
@@ -0,0 +1,43 @@
+From d210fab9154aa4ba45816e96b8b1fc4caebaeb01 Mon Sep 17 00:00:00 2001
+From: Yuchou Gan <yuchou.gan at nxp.com>
+Date: Fri, 1 Apr 2016 01:59:39 +0800
+Subject: [PATCH 26/31] MGS-1721 [#ccc] fix broken build on AArch64
+
+modify the type of structure TEXDIRECTVIVDATA's member to fit the 32-bit and 64-bit OS
+
+Signed-off-by: Gan Yuchou <yuchou.gan at nxp.com>
+---
+ retrace/glretrace.py | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/retrace/glretrace.py b/retrace/glretrace.py
+index 6b5608b..870c84a 100644
+--- a/retrace/glretrace.py
++++ b/retrace/glretrace.py
+@@ -657,7 +657,7 @@ _validateActiveProgram(trace::Call &call);
+ 
+ typedef struct TexDirectVivData
+ {
+-    GLuint   logical; // used for glTexDirectVIVMap/glTexDirectMapVIV/glTexDirectTiledMapVIV
++    uintptr_t   logical; // used for glTexDirectVIVMap/glTexDirectMapVIV/glTexDirectTiledMapVIV
+     GLuint   physical;
+     GLuint   index;
+     uint32_t size;
+@@ -668,12 +668,12 @@ static std::map<GLint, TEXDIRECTVIVDATA> _directTextureDataMap;
+ 
+ #include <g2d.h>
+ 
+-static void * alloc_dma_buffer(int size, unsigned int *logical, unsigned int *physical)
++static void * alloc_dma_buffer(int size, uintptr_t *logical, unsigned int *physical)
+ {
+     struct g2d_buf *buf = g2d_alloc(size, 0);
+     if(buf != NULL)
+     {
+-        *logical = (unsigned int)buf->buf_vaddr;
++        *logical = (uintptr_t)buf->buf_vaddr;
+         *physical = (unsigned int)buf->buf_paddr ;
+     }
+     return buf;
+-- 
+2.7.4
+
diff --git a/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0027-MGS-1859-ccc-blank-screen-when-retracing-es20-sdk-ap.patch b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0027-MGS-1859-ccc-blank-screen-when-retracing-es20-sdk-ap.patch
new file mode 100644
index 0000000..8c5588c
--- /dev/null
+++ b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0027-MGS-1859-ccc-blank-screen-when-retracing-es20-sdk-ap.patch
@@ -0,0 +1,58 @@
+From 6d25ba9cff1736fc69e4b7e0a3b5062545e9c128 Mon Sep 17 00:00:00 2001
+From: Yuchou Gan <yuchou.gan at nxp.com>
+Date: Fri, 3 Jun 2016 17:16:44 +0800
+Subject: [PATCH 27/31] MGS-1859 [#ccc] blank screen when retracing es20 sdk
+ app DirectMultiSamplingVideoYUV_FB
+
+Add GL_ALPHA and GL_LUMINANCE8_ALPHA8_EXT format support for
+
+glTexDirectVIVMap and glTexDirectInvalidateVIV.
+
+Date June 3, 2016
+Signed-off-by: Gan Yuchou <yuchou.gan at nxp.com>
+---
+ retrace/glretrace.py | 4 ++++
+ wrappers/egltrace.py | 6 ++++++
+ 2 files changed, 10 insertions(+)
+
+diff --git a/retrace/glretrace.py b/retrace/glretrace.py
+index 870c84a..9618e52 100644
+--- a/retrace/glretrace.py
++++ b/retrace/glretrace.py
+@@ -196,8 +196,12 @@ class GlRetracer(Retracer):
+             print '    case GL_VIV_YUY2:'
+             print '    case GL_VIV_UYVY:'
+             print '    case GL_RGB565_OES:'
++            print '    case GL_LUMINANCE8_ALPHA8_EXT:'
+             print '        size=width * height *2;'
+             print '        break;'
++            print '    case GL_ALPHA:'
++            print '        size=width * height;'
++            print '        break;'
+             print '    default:'
+             print '        break;'
+             print '    }'
+diff --git a/wrappers/egltrace.py b/wrappers/egltrace.py
+index 683f562..572e67c 100644
+--- a/wrappers/egltrace.py
++++ b/wrappers/egltrace.py
+@@ -94,10 +94,16 @@ class EglTracer(GlTracer):
+             print '    case GL_VIV_YUY2:'
+             print '    case GL_VIV_UYVY:'
+             print '    case GL_RGB565_OES:'
++            print '    case GL_LUMINANCE8_ALPHA8_EXT:'
+             print '        ysize=data.width * data.height *2;'
+             print '        usize=0;'
+             print '        vsize=0;'
+             print '        break;'
++            print '    case GL_ALPHA:'
++            print '        ysize=data.width * data.height;'
++            print '        usize=0;'
++            print '        vsize=0;'
++            print '        break;'
+             print '    default:'
+             print '        return;'
+             print '    }'
+-- 
+2.7.4
+
diff --git a/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0028-MGS-2254-ccc-add-the-TOT-commit-SHA1-inside-the-bina.patch b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0028-MGS-2254-ccc-add-the-TOT-commit-SHA1-inside-the-bina.patch
new file mode 100644
index 0000000..9a42cd5
--- /dev/null
+++ b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0028-MGS-2254-ccc-add-the-TOT-commit-SHA1-inside-the-bina.patch
@@ -0,0 +1,55 @@
+From 71899da21295172c21d0a8422af91063cda4e569 Mon Sep 17 00:00:00 2001
+From: Yuchou Gan <yuchou.gan at nxp.com>
+Date: Tue, 20 Sep 2016 00:39:13 +0800
+Subject: [PATCH 28/31] MGS-2254 [#ccc] add the TOT commit SHA1 inside the
+ binary
+
+Print the Tip Of Tree commit SHA1.
+In this way, we know which commit is in the released apitrace.
+
+Date: Sep 19, 2016
+Signed-off-by: Yuchou Gan <yuchou.gan at nxp.com>
+---
+ cli/CMakeLists.txt | 2 ++
+ cli/cli_main.cpp   | 8 ++++++++
+ 2 files changed, 10 insertions(+)
+
+diff --git a/cli/CMakeLists.txt b/cli/CMakeLists.txt
+index 4c13c21..9b621bb 100644
+--- a/cli/CMakeLists.txt
++++ b/cli/CMakeLists.txt
+@@ -3,10 +3,12 @@
+ # TODO: Use the same directory layout, for both build and install directories,
+ # so that binaries can find each other using just relative paths.
+ #
++execute_process(COMMAND git log --pretty=format:"%h" -n 1 OUTPUT_VARIABLE GIT_STRING)
+ add_definitions(
+     -DAPITRACE_PROGRAMS_INSTALL_DIR="${CMAKE_INSTALL_PREFIX}/bin"
+     -DAPITRACE_SCRIPTS_INSTALL_DIR="${CMAKE_INSTALL_PREFIX}/${SCRIPTS_INSTALL_DIR}"
+     -DAPITRACE_WRAPPERS_INSTALL_DIR="${CMAKE_INSTALL_PREFIX}/${WRAPPER_INSTALL_DIR}"
++    -DGIT_STRING="${GIT_STRING}"
+ )
+ if (WIN32)
+     add_definitions (-DAPITRACE_PYTHON_EXECUTABLE="python")
+diff --git a/cli/cli_main.cpp b/cli/cli_main.cpp
+index 2317be2..31e8b85 100644
+--- a/cli/cli_main.cpp
++++ b/cli/cli_main.cpp
+@@ -40,6 +40,14 @@
+ 
+ #define ARRAY_SIZE(arr) (sizeof (arr) / sizeof (arr[0]))
+ 
++#define _TXT2STR(t) #t
++#define TXT2STR(t) _TXT2STR(t)
++const char * VERSION = "\n\0$VERSION$"
++#ifdef GIT_STRING
++                            TXT2STR(GIT_STRING)
++#endif
++                            "$\n";
++
+ static const char *help_synopsis = "Print detailed help for the given command.";
+ 
+ static void list_commands(void);
+-- 
+2.7.4
+
diff --git a/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0029-MGS-815-ccc-avoid-memcpy-in-glTexDirectInvalidateVIV.patch b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0029-MGS-815-ccc-avoid-memcpy-in-glTexDirectInvalidateVIV.patch
new file mode 100644
index 0000000..12b328c
--- /dev/null
+++ b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0029-MGS-815-ccc-avoid-memcpy-in-glTexDirectInvalidateVIV.patch
@@ -0,0 +1,283 @@
+From c460694f65760abc04cebb01db77a95da5d06c3e Mon Sep 17 00:00:00 2001
+From: Yang Dong <b56112 at freescale.com>
+Date: Thu, 20 Apr 2017 11:24:35 +0300
+Subject: [PATCH 29/31] MGS-815 [#ccc] avoid memcpy in glTexDirectInvalidateVIV
+
+When a trace file is replayed, glTexDirectInvalidateVIV will
+trigger a memcpy to update the texture data.
+
+However, this data update is implemented by hardware in real mode.
+In order to achieve the realtime performance in apitrace,
+discard the memcpy used to update the VIV texture in performance mode.
+
+Signed-off-by: Yang Dong <b56112 at freescale.com>
+---
+ common/trace_parser.cpp       |  5 +++++
+ common/trace_parser.hpp       |  2 ++
+ common/trace_writer_local.cpp | 23 +++++++++++++++++++++++
+ common/trace_writer_local.hpp |  2 ++
+ retrace/retrace.hpp           |  4 ++++
+ retrace/retrace_main.cpp      | 15 ++++++++++++++-
+ retrace/retrace_stdc.cpp      | 36 ++++++++++++++++++++++++++++++++++++
+ wrappers/egltrace.py          |  8 ++++----
+ wrappers/trace.py             |  3 +++
+ 9 files changed, 93 insertions(+), 5 deletions(-)
+
+diff --git a/common/trace_parser.cpp b/common/trace_parser.cpp
+index 99fa5e8..bcc7b9f 100644
+--- a/common/trace_parser.cpp
++++ b/common/trace_parser.cpp
+@@ -70,6 +70,7 @@ bool Parser::open(const char *filename) {
+         return false;
+     }
+     api = API_UNKNOWN;
++    skip_spec_call = false;
+ 
+     return true;
+ }
+@@ -442,6 +443,10 @@ void Parser::parse_enter(Mode mode) {
+ 
+     call->no = next_call_no++;
+ 
++    if((skip_spec_call == true)&&(sig->id==4)) {
++        mode = SCAN;
++    }
++
+     if (parse_call_details(call, mode)) {
+         calls.push_back(call);
+     } else {
+diff --git a/common/trace_parser.hpp b/common/trace_parser.hpp
+index b638aa1..1403b28 100644
+--- a/common/trace_parser.hpp
++++ b/common/trace_parser.hpp
+@@ -56,6 +56,8 @@ public:
+     virtual bool open(const char *filename) = 0;
+     virtual void close(void) = 0;
+     virtual unsigned long long getVersion(void) const = 0;
++public:
++    bool skip_spec_call;
+ };
+ 
+ 
+diff --git a/common/trace_writer_local.cpp b/common/trace_writer_local.cpp
+index 17b6328..d792f87 100644
+--- a/common/trace_writer_local.cpp
++++ b/common/trace_writer_local.cpp
+@@ -55,6 +55,9 @@ const FunctionSig free_sig = {2, "free", 1, free_args};
+ static const char *realloc_args[2] = {"ptr", "size"};
+ const FunctionSig realloc_sig = {3, "realloc", 2, realloc_args};
+ 
++static const char *memcpy_opt_args[3] = {"dest", "src", "n"};
++const FunctionSig memcpy_opt_sig = {0xFFFF, "memcpy_opt", 3, memcpy_opt_args};
++
+ 
+ static void exceptionCallback(void)
+ {
+@@ -316,6 +319,26 @@ void fakeMemcpy(const void *ptr, size_t size) {
+     localWriter.endLeave();
+ }
+ 
++void fakeMemcpyOpt(const void *ptr, size_t size) {
++    assert(ptr);
++    if (!size) {
++        return;
++    }
++    unsigned _call = localWriter.beginEnter(&memcpy_opt_sig, true);
++    localWriter.beginArg(0);
++    localWriter.writePointer((uintptr_t)ptr);
++    localWriter.endArg();
++    localWriter.beginArg(1);
++    localWriter.writeBlob(ptr, size);
++    localWriter.endArg();
++    localWriter.beginArg(2);
++    localWriter.writeUInt(size);
++    localWriter.endArg();
++    localWriter.endEnter();
++    localWriter.beginLeave(_call);
++    localWriter.endLeave();
++}
++
+ 
+ } /* namespace trace */
+ 
+diff --git a/common/trace_writer_local.hpp b/common/trace_writer_local.hpp
+index ed27dbb..0dbc96f 100644
+--- a/common/trace_writer_local.hpp
++++ b/common/trace_writer_local.hpp
+@@ -142,5 +142,7 @@ namespace trace {
+ 
+     void fakeMemcpy(const void *ptr, size_t size);
+ 
++    void fakeMemcpyOpt(const void *ptr, size_t size);
++
+ } /* namespace trace */
+ 
+diff --git a/retrace/retrace.hpp b/retrace/retrace.hpp
+index 1c9f0e6..1b1a6e1 100644
+--- a/retrace/retrace.hpp
++++ b/retrace/retrace.hpp
+@@ -134,6 +134,10 @@ extern bool profilingMemoryUsage;
+ extern bool dumpingState;
+ extern bool dumpingSnapshots;
+ 
++/**
++ * Whether to discard the memcpy called by the VIV texture.
++ */
++extern bool performance;
+ 
+ enum Driver {
+     DRIVER_DEFAULT,
+diff --git a/retrace/retrace_main.cpp b/retrace/retrace_main.cpp
+index 72e0183..95ca24c 100644
+--- a/retrace/retrace_main.cpp
++++ b/retrace/retrace_main.cpp
+@@ -35,6 +35,10 @@
+ #include <fcntl.h>
+ #endif
+ 
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <fcntl.h>
++
+ #include "os_binary.hpp"
+ #include "os_crtdbg.hpp"
+ #include "os_time.hpp"
+@@ -98,6 +102,7 @@ bool profilingPixelsDrawn = false;
+ bool profilingMemoryUsage = false;
+ bool useCallNos = true;
+ bool singleThread = false;
++bool performance = false;
+ 
+ unsigned frameNo = 0;
+ unsigned callNo = 0;
+@@ -633,7 +638,9 @@ usage(const char *argv0) {
+         "      --dump-format=FORMAT dump state format (`json` or `ubjson`)\n"
+         "  -w, --wait              waitOnFinish on final frame\n"
+         "      --loop[=N]          loop N times (N<0 continuously) replaying final frame.\n"
+-        "      --singlethread      use a single thread to replay command stream\n";
++        "      --singlethread      use a single thread to replay command stream\n"
++        "      --performance       discard the memcpy in retrace egl VIV extension\n"
++        ;
+ }
+ 
+ enum {
+@@ -657,6 +664,7 @@ enum {
+     SNAPSHOT_STARTFRAME_OPT,
+     SNAPSHOT_STOPFRAME_OPT,
+     REFERENCE_DUMP_OPT,
++    PERFORMANCE_OPT,
+ };
+ 
+ const static char *
+@@ -692,6 +700,7 @@ longOptions[] = {
+     {"snapshot-start", required_argument, 0, SNAPSHOT_STARTFRAME_OPT},
+     {"snapshot-stop", required_argument, 0, SNAPSHOT_STOPFRAME_OPT},
+     {"reference-dump", required_argument, 0, REFERENCE_DUMP_OPT},
++    {"performance", no_argument, 0, PERFORMANCE_OPT},
+     {0, 0, 0, 0}
+ };
+ 
+@@ -928,6 +937,10 @@ int main(int argc, char **argv)
+                 return 1;
+             }
+             break;
++        case PERFORMANCE_OPT:
++            retrace::performance = true;
++            parser->skip_spec_call = true;
++            break;
+         default:
+             std::cerr << "error: unknown option " << opt << "\n";
+             usage(argv[0]);
+diff --git a/retrace/retrace_stdc.cpp b/retrace/retrace_stdc.cpp
+index 2a57ef0..8a862ac 100644
+--- a/retrace/retrace_stdc.cpp
++++ b/retrace/retrace_stdc.cpp
+@@ -82,8 +82,44 @@ static void retrace_memcpy(trace::Call &call) {
+ }
+ 
+ 
++static void retrace_memcpy_opt(trace::Call &call) {
++    if(retrace::performance==true)
++    {
++        return;
++    }
++
++    void * destPtr;
++    size_t destLen;
++    retrace::toRange(call.arg(0), destPtr, destLen);
++
++    void * srcPtr;
++    size_t srcLen;
++    retrace::toRange(call.arg(1), srcPtr, srcLen);
++
++    size_t n = call.arg(2).toUInt();
++
++    if (!destPtr || !srcPtr || !n) {
++        return;
++    }
++
++    if (n > destLen) {
++        retrace::warning(call) << "dest buffer overflow of " << n - destLen << " bytes\n";
++    }
++
++    if (n > srcLen) {
++        retrace::warning(call) << "src buffer overflow of " << n - srcLen << " bytes\n";
++    }
++
++    n = std::min(n, destLen);
++    n = std::min(n, srcLen);
++
++    memcpy(destPtr, srcPtr, n);
++}
++
++
+ const retrace::Entry retrace::stdc_callbacks[] = {
+     {"malloc", &retrace_malloc},
+     {"memcpy", &retrace_memcpy},
++    {"memcpy_opt", &retrace_memcpy_opt},
+     {NULL, NULL}
+ };
+diff --git a/wrappers/egltrace.py b/wrappers/egltrace.py
+index 572e67c..9a292da 100644
+--- a/wrappers/egltrace.py
++++ b/wrappers/egltrace.py
+@@ -109,18 +109,18 @@ class EglTracer(GlTracer):
+             print '    }'
+             print '    if (NULL==(GLvoid*)data.logical) {'
+             print '        if (ysize > 0) {'
+-            self.emit_memcpy('(GLvoid*)data.planes[0]', 'ysize')
++            self.emit_memcpy_opt('(GLvoid*)data.planes[0]', 'ysize')
+             print '         }'
+             print '        if (usize > 0) {'
+-            self.emit_memcpy('(GLvoid*)data.planes[1]', 'usize')
++            self.emit_memcpy_opt('(GLvoid*)data.planes[1]', 'usize')
+             print '         }'
+             print '        if (vsize > 0) {'
+-            self.emit_memcpy('(GLvoid*)data.planes[2]', 'vsize')
++            self.emit_memcpy_opt('(GLvoid*)data.planes[2]', 'vsize')
+             print '         }'
+             print '    } else {'
+             print '        size = ysize + usize + vsize;'
+             print '        if (size > 0) {'
+-            self.emit_memcpy('(GLvoid*)data.logical', 'size')
++            self.emit_memcpy_opt('(GLvoid*)data.logical', 'size')
+             print '         }'
+             print '    }'
+ 
+diff --git a/wrappers/trace.py b/wrappers/trace.py
+index efb2fd5..7d1baa1 100644
+--- a/wrappers/trace.py
++++ b/wrappers/trace.py
+@@ -972,6 +972,9 @@ class Tracer:
+     def emit_memcpy(self, ptr, size):
+         print '    trace::fakeMemcpy(%s, %s);' % (ptr, size)
+     
++    def emit_memcpy_opt(self, ptr, size):
++        print '    trace::fakeMemcpyOpt(%s, %s);' % (ptr, size)
++
+     def fake_call(self, function, args):
+         print '            unsigned _fake_call = trace::localWriter.beginEnter(&_%s_sig, true);' % (function.name,)
+         for arg, instance in zip(function.args, args):
+-- 
+2.7.4
+
diff --git a/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0030-MGS-814-ccc-retrace-support-eglCreatePixmapSurface-o.patch b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0030-MGS-814-ccc-retrace-support-eglCreatePixmapSurface-o.patch
new file mode 100644
index 0000000..9c0315d
--- /dev/null
+++ b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0030-MGS-814-ccc-retrace-support-eglCreatePixmapSurface-o.patch
@@ -0,0 +1,98 @@
+From 5645e1fbf239be0a3f5af059057cc8c381acbf0e Mon Sep 17 00:00:00 2001
+From: Yang Dong <b56112 at freescale.com>
+Date: Thu, 20 Apr 2017 11:58:48 +0300
+Subject: [PATCH 30/31] MGS-814 [#ccc] retrace: support eglCreatePixmapSurface
+ on NonX backend
+
+Signed-off-by: Yang Dong <b56112 at freescale.com>
+---
+ retrace/glretrace.hpp     |  3 +++
+ retrace/glretrace_egl.cpp | 26 +++++++++++++++++++++++++-
+ retrace/glretrace_ws.cpp  |  6 ++++++
+ 3 files changed, 34 insertions(+), 1 deletion(-)
+
+diff --git a/retrace/glretrace.hpp b/retrace/glretrace.hpp
+index 7e26d6d..f75b516 100644
+--- a/retrace/glretrace.hpp
++++ b/retrace/glretrace.hpp
+@@ -96,6 +96,9 @@ glws::Drawable *
+ createDrawable(glprofile::Profile profile);
+ 
+ glws::Drawable *
++createPixmapDrawable(glprofile::Profile profile);
++
++glws::Drawable *
+ createDrawable(void);
+ 
+ glws::Drawable *
+diff --git a/retrace/glretrace_egl.cpp b/retrace/glretrace_egl.cpp
+index c6fabdd..d1e63ed 100644
+--- a/retrace/glretrace_egl.cpp
++++ b/retrace/glretrace_egl.cpp
+@@ -118,6 +118,24 @@ static void createDrawable(unsigned long long orig_config, unsigned long long or
+     drawable_map[orig_surface] = drawable;
+ }
+ 
++static void createPixmapDrawable(unsigned long long orig_config, unsigned long long orig_surface)
++{
++    ProfileMap::iterator it = profile_map.find(orig_config);
++    glprofile::Profile profile;
++
++    // If the requested config is associated with a profile, use that
++    // profile. Otherwise, assume that the last used profile is what
++    // the user wants.
++    if (it != profile_map.end()) {
++        profile = it->second;
++    } else {
++        profile = last_profile;
++    }
++
++    glws::Drawable *drawable = glretrace::createPixmapDrawable(profile);
++    drawable_map[orig_surface] = drawable;
++}
++
+ static void retrace_eglChooseConfig(trace::Call &call) {
+     if (!call.ret->toSInt()) {
+         return;
+@@ -166,6 +184,12 @@ static void retrace_eglCreatePbufferSurface(trace::Call &call) {
+     // TODO: Respect the pbuffer dimensions too
+ }
+ 
++static void retrace_eglCreatePixmapSurface(trace::Call &call) {
++    unsigned long long orig_config = call.arg(1).toUIntPtr();
++    unsigned long long orig_surface = call.ret->toUIntPtr();
++    createPixmapDrawable(orig_config, orig_surface);
++}
++
+ static void retrace_eglDestroySurface(trace::Call &call) {
+     unsigned long long orig_surface = call.arg(1).toUIntPtr();
+ 
+@@ -293,7 +317,7 @@ const retrace::Entry glretrace::egl_callbacks[] = {
+     {"eglGetConfigAttrib", &retrace::ignore},
+     {"eglCreateWindowSurface", &retrace_eglCreateWindowSurface},
+     {"eglCreatePbufferSurface", &retrace_eglCreatePbufferSurface},
+-    //{"eglCreatePixmapSurface", &retrace::ignore},
++    {"eglCreatePixmapSurface", &retrace_eglCreatePixmapSurface},
+     {"eglDestroySurface", &retrace_eglDestroySurface},
+     {"eglQuerySurface", &retrace::ignore},
+     {"eglBindAPI", &retrace_eglBindAPI},
+diff --git a/retrace/glretrace_ws.cpp b/retrace/glretrace_ws.cpp
+index 4d617f7..376b055 100644
+--- a/retrace/glretrace_ws.cpp
++++ b/retrace/glretrace_ws.cpp
+@@ -99,6 +99,12 @@ createDrawable(glprofile::Profile profile) {
+ 
+ 
+ glws::Drawable *
++createPixmapDrawable(glprofile::Profile profile) {
++    return createDrawableHelper(profile, false, true);
++}
++
++
++glws::Drawable *
+ createDrawable(void) {
+     return createDrawable(defaultProfile);
+ }
+-- 
+2.7.4
+
diff --git a/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0031-libbacktrace-define-HAVE_STDINT_H-in-config.h.patch b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0031-libbacktrace-define-HAVE_STDINT_H-in-config.h.patch
new file mode 100644
index 0000000..1f89b19
--- /dev/null
+++ b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0031-libbacktrace-define-HAVE_STDINT_H-in-config.h.patch
@@ -0,0 +1,36 @@
+From 2ce83ecdb8c5dbe8c9e2d3375a789f4fdddc72f1 Mon Sep 17 00:00:00 2001
+From: Adrian Negreanu <groleo at gmail.com>
+Date: Tue, 25 Apr 2017 17:00:03 +0300
+Subject: [PATCH 31/31] libbacktrace: define HAVE_STDINT_H in config.h
+
+---
+ thirdparty/libbacktrace/backtrace.h       | 1 +
+ thirdparty/libbacktrace/config.h.in.cmake | 3 +++
+ 2 files changed, 4 insertions(+)
+
+diff --git a/thirdparty/libbacktrace/backtrace.h b/thirdparty/libbacktrace/backtrace.h
+index da16e3d..553e561 100644
+--- a/thirdparty/libbacktrace/backtrace.h
++++ b/thirdparty/libbacktrace/backtrace.h
+@@ -35,6 +35,7 @@ POSSIBILITY OF SUCH DAMAGE.  */
+ 
+ #include <stddef.h>
+ #include <stdio.h>
++#include "config.h"
+ 
+ /* We want to get a definition for uintptr_t, but we still care about
+    systems that don't have <stdint.h>.  */
+diff --git a/thirdparty/libbacktrace/config.h.in.cmake b/thirdparty/libbacktrace/config.h.in.cmake
+index 4ac1326..2178416 100644
+--- a/thirdparty/libbacktrace/config.h.in.cmake
++++ b/thirdparty/libbacktrace/config.h.in.cmake
+@@ -22,3 +22,6 @@
+ 
+ /* Define to 1 if dwarf.h is in the libdwarf folder */
+ #cmakedefine HAVE_LIBDWARF_DWARF_H 1
++
++/* Define to 1 if you have the <stdint.h> header file. */
++#cmakedefine HAVE_STDINT_H @HAVE_STDINT_H@
+-- 
+2.7.4
+
diff --git a/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0032-changed-disable-X11-mechanism.patch b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0032-changed-disable-X11-mechanism.patch
new file mode 100644
index 0000000..64ed8a1
--- /dev/null
+++ b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0032-changed-disable-X11-mechanism.patch
@@ -0,0 +1,18 @@
+--- a/CMakeLists.txt	2017-04-26 12:05:19.511369999 +0300
++++ b/CMakeLists.txt	2017-04-26 12:06:46.651930949 +0300
+@@ -144,7 +144,14 @@
+ elseif (APPLE)
+     set (ENABLE_EGL false)
+ else ()
+-    find_package (X11)
++
++    if (NOT DISABLE_X11)
++        message ("DISABLE_X11 is not set")
++        find_package (X11)
++    else ()
++        message ("DISABLE_X11 is set")
++        set (X11_FOUND false)
++    endif ()
+ 
+     if (X11_FOUND)
+         include_directories (${X11_INCLUDE_DIR})
diff --git a/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0033-MGS-2963-ccc-Miss-usr-bin-eglretrace-file-in-FB-and-.patch b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0033-MGS-2963-ccc-Miss-usr-bin-eglretrace-file-in-FB-and-.patch
new file mode 100644
index 0000000..fa031bb
--- /dev/null
+++ b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0033-MGS-2963-ccc-Miss-usr-bin-eglretrace-file-in-FB-and-.patch
@@ -0,0 +1,70 @@
+From f35af2704c6e8a1552b0df37f69afeb4265a6c4b Mon Sep 17 00:00:00 2001
+From: Adrian Negreanu <adrian.negreanu at nxp.com>
+Date: Thu, 8 Jun 2017 18:08:03 +0300
+Subject: [PATCH] MGS-2963 [#ccc] Miss /usr/bin/eglretrace file in FB and XWLD
+ rootfs.
+
+Not yet upstreamable since the NonX backend is not yet upstream.
+
+Upstream-Status: Inappropriate [other]
+Signed-off-by: Adrian Negreanu <adrian.negreanu at nxp.com>
+---
+ retrace/glws_nonx.cpp | 29 +++++++++++++++++++++++++----
+ 1 file changed, 25 insertions(+), 4 deletions(-)
+
+diff --git a/retrace/glws_nonx.cpp b/retrace/glws_nonx.cpp
+index fa8db97..18df45a 100644
+--- a/retrace/glws_nonx.cpp
++++ b/retrace/glws_nonx.cpp
+@@ -74,8 +74,8 @@ public:
+     EGLNativePixmapType native_pixmap;
+     EGLenum api;
+ 
+-    NonxDrawable(const Visual *vis, int w, int h, bool pbuffer) :
+-        Drawable (vis, w, h, pbuffer),
++    NonxDrawable(const Visual *vis, int w, int h, const pbuffer_info *info) :
++        Drawable (vis, w, h, info),
+         api(EGL_OPENGL_ES_API)
+     {
+         native_pixmap = (EGLNativePixmapType)0;
+@@ -387,9 +387,10 @@ createVisual(bool doubleBuffer, unsigned samples, Profile profile) {
+ }
+ 
+ Drawable *
+-createDrawable(const Visual *visual, int width, int height, bool pbuffer)
++createDrawable(const Visual *visual, int width, int height,
++        const pbuffer_info *info)
+ {
+-    return new NonxDrawable(visual, width, height, pbuffer);
++    return new NonxDrawable(visual, width, height, info);
+ }
+ 
+ Context *
+@@ -492,4 +493,24 @@ processEvents(void)
+     return false;
+ }
+ 
++bool
++bindTexImage(Drawable *pBuffer, int iBuffer) {
++    std::cerr << "error: NonX::wglBindTexImageARB not implemented.\n";
++    assert(pBuffer->pbuffer);
++    return true;
++}
++
++bool
++releaseTexImage(Drawable *pBuffer, int iBuffer) {
++    std::cerr << "error: NonX::wglReleaseTexImageARB not implemented.\n";
++    assert(pBuffer->pbuffer);
++    return true;
++}
++
++bool
++setPbufferAttrib(Drawable *pBuffer, const int *attribList) {
++    assert(pBuffer->pbuffer);
++    return true;
++}
++
+ }
+-- 
+2.7.4
+
diff --git a/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0034-MGS-make-multiarch-optional.patch b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0034-MGS-make-multiarch-optional.patch
new file mode 100644
index 0000000..d12346a
--- /dev/null
+++ b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0034-MGS-make-multiarch-optional.patch
@@ -0,0 +1,22 @@
+Index: git/CMakeLists.txt
+===================================================================
+--- git.orig/CMakeLists.txt	2017-06-13 16:30:37.707992787 -0500
++++ git/CMakeLists.txt	2017-06-13 16:40:37.534967169 -0500
+@@ -40,6 +40,8 @@
+ 
+ option (ENABLE_EGL "Enable EGL support." ON)
+ 
++option (ENABLE_MULTIARCH "Enable multiarch support." ON)
++
+ option (ENABLE_WAFFLE "Enable WAFFLE support." OFF)
+ 
+ option (ENABLE_FRAME_POINTER "Disable frame pointer omission" ON)
+@@ -377,7 +379,7 @@
+ ##############################################################################
+ # Installation directories
+ 
+-if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
++if (ENABLE_MULTIARCH AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
+     # Debian multiarch support
+     execute_process(COMMAND dpkg-architecture -qDEB_HOST_MULTIARCH
+         OUTPUT_VARIABLE ARCH_SUBDIR
diff --git a/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0035-dlopen-don-t-override-symbols-in-Vivante-libs.patch b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0035-dlopen-don-t-override-symbols-in-Vivante-libs.patch
new file mode 100644
index 0000000..5ba5794
--- /dev/null
+++ b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace/0035-dlopen-don-t-override-symbols-in-Vivante-libs.patch
@@ -0,0 +1,101 @@
+From 33f1a0293d2c16068d4da1d3c4da9004f4f6a5ef Mon Sep 17 00:00:00 2001
+From: Adrian Negreanu <adrian.negreanu at nxp.com>
+Date: Mon, 10 Jul 2017 22:13:44 +0300
+Subject: [PATCH] dlopen: don't override symbols in Viv libs
+
+---
+ wrappers/egltrace.py | 20 +++++++++++++++++++-
+ wrappers/glxtrace.py | 20 ++++++++++++++++++--
+ 2 files changed, 37 insertions(+), 3 deletions(-)
+
+diff --git a/wrappers/egltrace.py b/wrappers/egltrace.py
+index 9a292da..f7f03db 100644
+--- a/wrappers/egltrace.py
++++ b/wrappers/egltrace.py
+@@ -318,6 +318,19 @@ void * dlopen(const char *filename, int flag)
+             strcmp(filename, "libGL.so") == 0 ||
+             strcmp(filename, "libGL.so.1") == 0;
+ 
++        void *caller = __builtin_return_address(0);
++        Dl_info info;
++        if (dladdr(caller, &info)) {
++            const char *caller_module = info.dli_fname;
++            os::log("apitrace: dlopen(%s) called from %s\n", filename, caller_module);
++            if ( (strcmp(caller_module, "/usr/lib/libGAL.so") == 0)
++              || (strcmp(caller_module, "/usr/lib/libVDK.so") == 0)
++               )
++            {
++                intercept = false;
++            }
++        }
++
+         if (intercept) {
+             os::log("apitrace: redirecting dlopen(\"%s\", 0x%x)\n", filename, flag);
+ 
+@@ -332,7 +345,11 @@ void * dlopen(const char *filename, int flag)
+         }
+     }
+ 
+-    void *handle = _dlopen(filename, flag);
++    void *handle = _dlopen(filename, RTLD_NOW);
++    if (!handle) {
++        os::log("apitrace: warning: dlopen(%s,%x) failed %s\n", filename, flag, dlerror());
++        return handle;
++    }
+ 
+     if (intercept) {
+         // Get the file path for our shared object, and use it instead
+@@ -353,6 +370,7 @@ void * dlopen(const char *filename, int flag)
+         }
+     }
+ 
++    os::log("apitrace: %p\n", handle);
+     return handle;
+ }
+ 
+diff --git a/wrappers/glxtrace.py b/wrappers/glxtrace.py
+index e2d0fc4..ee5097d 100644
+--- a/wrappers/glxtrace.py
++++ b/wrappers/glxtrace.py
+@@ -198,7 +198,11 @@ void * dlopen(const char *filename, int flag)
+ {
+     void *handle;
+ 
+-    handle = _dlopen(filename, flag);
++    handle = _dlopen(filename, RTLD_NOW);
++    if (!handle) {
++        os::log("apitrace: warning: dlopen(%s,%x) failed %s\n", filename, flag, dlerror());
++        return handle;
++    }
+ 
+     const char * libgl_filename = getenv("TRACE_LIBGL");
+ 
+@@ -211,12 +215,24 @@ void * dlopen(const char *filename, int flag)
+         if (strcmp(filename, "libGL.so") == 0 ||
+             strcmp(filename, "libGL.so.1") == 0) {
+ 
++            void *caller = __builtin_return_address(0);
++            Dl_info info;
++            if (dladdr(caller, &info)) {
++                const char *caller_module = info.dli_fname;
++                os::log("apitrace: dlopen(%s) called from %s\n", filename, caller_module);
++                if ( (strcmp(caller_module, "/usr/lib/libGAL.so") == 0)
++                  || (strcmp(caller_module, "/usr/lib/libVDK.so") == 0)
++                   )
++                {
++                    return handle;
++                }
++            }
++
+             // Use the true libGL.so handle instead of RTLD_NEXT from now on
+             _libGlHandle = handle;
+ 
+             // Get the file path for our shared object, and use it instead
+             static int dummy = 0xdeedbeef;
+-            Dl_info info;
+             if (dladdr(&dummy, &info)) {
+                 os::log("apitrace: redirecting dlopen(\"%s\", 0x%x)\n", filename, flag);
+                 handle = _dlopen(info.dli_fname, flag);
+-- 
+2.7.4
+
diff --git a/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace_7.1.0.bb b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace_7.1.0.bb
new file mode 100644
index 0000000..acad772
--- /dev/null
+++ b/recipes-graphics/imx-gpu-apitrace/imx-gpu-apitrace_7.1.0.bb
@@ -0,0 +1,57 @@
+SUMMARY = "Samples for OpenGL ES"
+LICENSE = "MIT"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=aeb969185a143c3c25130bc2c3ef9a50"
+DEPENDS = "virtual/libg2d imx-gpu-viv zlib libpng procps"
+
+SRC_URI = "git://github.com/apitrace/apitrace.git;nobranch=1;tag=7.1 \
+          file://0001-add-docs-HOWTO.markdown.patch \
+          file://0002-add-docs-Freescale_apitrace_user_guide.markdown.patch \
+          file://0003-add-docs-Freescale_apitrace.markdown.patch \
+          file://0004-add-docs-apitrace_test.markdown.patch \
+          file://0005-add-apitrace_dalvik.sh.patch \
+          file://0006-add-test_android.sh.patch \
+          file://0007-add-test_yocto.sh.patch \
+          file://0009-add-retrace-glws_nonx.cpp.patch \
+          file://0010-cmake-use-glws_nonx-for-Vivante.patch \
+          file://0011-cli_trace-export-ENABLE_API_TRACE-1.patch \
+          file://0012-use-dlsym-to-get-function-pointers.patch \
+          file://0013-Vivante-driver-does-not-support-GL_RGB-in-openGL-dri.patch \
+          file://0014-MGS-469-GPU-hangs-when-retracing-OGLESParticles-on-m.patch \
+          file://0015-egl-define-egl-native-types-for-non-x11.patch \
+          file://0016-don-t-recreate-the-EGL-surface-on-resize.patch \
+          file://0017-add-Image-getMD5.patch \
+          file://0018-retrace-use-Image-getMD5-for-image-comparison.patch \
+          file://0019-egltrace-don-t-use-dlsym-on-aliased-functions.patch \
+          file://0020-egl-glx-trace-add-ApiTraceEnabled.patch \
+          file://0021-LocalWriter-make-a-writer-ignorable.patch \
+          file://0022-MGS-309-ccc-retrace-tutorial3-is-different-with-trac.patch \
+          file://0023-add-support-for-Vivante-extensions.patch \
+          file://0024-MGS-470-ccc-cannot-trace-mesa-demos-vertexrate.patch \
+          file://0025-MGS-1271-ccc-disable-X-debug-function.patch \
+          file://0026-MGS-1721-ccc-fix-broken-build-on-AArch64.patch \
+          file://0027-MGS-1859-ccc-blank-screen-when-retracing-es20-sdk-ap.patch \
+          file://0028-MGS-2254-ccc-add-the-TOT-commit-SHA1-inside-the-bina.patch \
+          file://0029-MGS-815-ccc-avoid-memcpy-in-glTexDirectInvalidateVIV.patch \
+          file://0030-MGS-814-ccc-retrace-support-eglCreatePixmapSurface-o.patch \
+          file://0031-libbacktrace-define-HAVE_STDINT_H-in-config.h.patch \
+          file://0032-changed-disable-X11-mechanism.patch \
+          file://0033-MGS-2963-ccc-Miss-usr-bin-eglretrace-file-in-FB-and-.patch \
+          file://0034-MGS-make-multiarch-optional.patch \
+          file://0035-dlopen-don-t-override-symbols-in-Vivante-libs.patch \
+"
+
+S = "${WORKDIR}/git"
+
+inherit cmake lib_package pkgconfig perlnative pythonnative
+
+EXTRA_OECMAKE += "-DENABLE_VIVANTE=ON -DENABLE_MULTIARCH=OFF"
+EXTRA_OECMAKE += \
+    "${@bb.utils.contains('DISTRO_FEATURES', 'wayland', '-DDISABLE_X11=ON', \
+        bb.utils.contains('DISTRO_FEATURES',     'x11', '', \
+                                                        '-DDISABLE_X11=ON', d), d)}"
+
+FILES_${PN} = "${bindir} ${libdir}"
+FILES_${PN}-dbg += "${libdir}/*/*/.debug"
+
+PACKAGE_ARCH = "${MACHINE_SOCARCH}"
+COMPATIBLE_MACHINE = "(mx6q|mx6dl|mx6sx|mx6sl|mx7ulp)"
-- 
1.9.1



More information about the meta-freescale mailing list