このドキュメントでは、OpenGL ES 2.0 または OpenVG を使用してハードウェア アクセラレーションを使用して画面上に何かを描画するための Cairo のセットアップについて説明します。
紹介:
ご存知のように、私が言及したライブラリ(OpenGL、ES、OpenVG)を使用して、imx6qのハードウェアアクセラレーションでフレームバッファに描画できますが、これらのライブラリを使用すると少し扱いが難しくなります。つまり、OpenGLまたはOpenVGを使用するのは一種の難しい仕事ですが、なぜですか?私はそれを明確にするためにここに例を持ってきましょう、あなたが姿勢航空機のシンボルを描きたいと想像してください、このシンボルは、それが含む完全な姿勢シンボルのように見えるように描画される要素のいくつかの必要があります。
1-サークル
2ライン張り
3-Text
4-トライアングル
5-いくつかのカスタム形状、たとえば、水平方向に描画される2本のLのような線
あなたがOpenGLと特にOpenGL ESの経験を持っている場合は、円、線、三角形などを描くことは本当に難しい仕事ではないことに気づくでしょう、もちろん、OpenGLでこれらのプリミティブを描画するには、コードのわずか3行でそれらを描画できるCairo APIとは対照的に、より多くのコード行が必要ですが、最も難しい仕事は、OpenGLで テキストを 描画することですあなたが対処しなければならない単純なテキストを描画したいときFreeTypeのような追加のライブラリがあります,...グリフ機能をフェッチし、その後、ビットマップテクスチャにテキストを描画するためにアトラスアプローチを使用して、アプリで文字が必要な場合は、テクスチャ内の前に保存されたグリフの文字の位置にアクセスできる、フェッチして使用することができます、また、この場合は2つの特定のOpenGL ESシェーダーで作業する必要があります。
ですから、OpenGLやOpenVGを使って図形を描くのは、本当に使いこなせる人や困りごとが多ければ大丈夫だと思います。:D個人的には、高レベルのAPIを使用してから、アプリケーションの他の側面に焦点を当てることを好みます。
カイロのコンパイル:
このドキュメントはCairoを構成またはコンパイルすることを意図したものではなく、OpenGL ESバックエンドを使用してYOCTO、Buildroot、またはその他の組み込みLinuxディストリビューションビルダーを使用して簡単に構成およびコンパイルできると確信しています(YOCTOとBuildrootは 組み込みLinuxディストリビューションではありません。カスタム1つを作成できます)手動でコンパイルすることもできます。
設定するには:
./configure --prefix=/home/super/Desktop/ROOTFS/MY_ROOTFS/usr --host=${CROSS_COMPILE} CFLAGS="-I/home/super/Desktop/ROOTFS/MY_ROOTFS/usr/include/ -DLINUX -DEGL_API_FB" LIBS="-L/home/super/Desktop/ROOTFS/MY_ROOTFS/usr/lib/ -lz" --enable-xlib=no --enable-egl --enable-glesv2
コンパイルするには:
作成する
ちなみに、あなたはあなた自身のボードに適した構成を見つけることができます。カイロには多くのオプションがあります。
カイロの表面を作る方法:
Cairoで図形を描画した経験がある場合は、cairo_t*タイプからAPIが動作し、画面上に形状が表示される描画機能へのサーフェスが必要であることをご存知でしょう。
OpenGL ES を使用する Cairo サーフェスを作成するには、EGL (EGL は Khronos レンダリング API (OpenGL、OpenGL ES、OpenVG など) と基礎となるネイティブ プラットフォーム ウィンドウ システムとの間のインターフェイスです)[1] を正しく設定し、そこから Cairo サーフェスを作成する必要があります。
EGLint config_attributes[] =
{
EGL_RENDERABLE_TYPE、
EGL_OPENGL_ES2_BIT,
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE、8、
EGL_BLUE_SIZE、8、
EGL_ALPHA_SIZE,EGL_DONT_CARE,
EGL_SURFACE_TYPE,EGL_WINDOW_BIT,
EGL_DEPTH_SIZE、16、
EGL_SAMPLES、4、
EGL_NONE
};
OpenVGでOpenGL ES v 2.0を変更する場合は、EGL_RENDERABLE_TYPE(つまりEGL_OPENGL_ES2_BIT)のパラメータをEGL_OPENVG_BITに変更するだけで十分です。
次のコードが図1の画面に表示されます。
図1:IMX6QでのCairoによる簡単な描画
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//========================================================================
// Name : testCairo.cpp
// Author : Ali Sarlak
// Version : 1.0
// Copyright : GPL
// Description : EGL+Cairo GLIB
//========================================================================
#include
#include
#include < EGL/egl.h>
#include < EGL/eglext.h>
#include < EGL/eglplatform.h>
#include < カイロ/cairo-gl.h>
#include < EGL/eglvivante.h>
#include
#define DISPLAY_WIDTH 640
#define DISPLAY_HEIGHT 480
名前空間 std を使用する 。
int main()
{
printf("開始\n");
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
EGLContext eglContext;
EGLSurface eglSurface;
EGLブーリーン結果B;
/* ディスプレイハンドルを取得し、EGL を初期化します */
EGLintメジャー、 マイナー;
EGLDisplay eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
resultB = eglInitialize(eglDisplay, &major , &minor );
EGLint config_attributes[] =
{
EGL_RENDERABLE_TYPE、
EGL_OPENGL_ES2_BIT,
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE、8、
EGL_BLUE_SIZE、8、
EGL_ALPHA_SIZE,EGL_DONT_CARE,
EGL_SURFACE_TYPE,EGL_WINDOW_BIT,
EGL_DEPTH_SIZE、16、
EGL_SAMPLES, 4,4
EGL_NONE
};
EGLint numberConfigs = 0;
EGLConfig* matchingConfigs=NULL;
if (EGL_FALSE
== eglChooseConfig(eglDisplay, config_attributes, NULL, 0, &numberConfigs))
{
printf("eglChooseConfig EROR\n");
}
if (numberConfigs == 0)
{
printf("eglChooseConfig EROR\n");
}
printf("構成の数 = %d\n", numberConfigs);
/* 一致する設定のリストを保存するためのスペースを確保します... */
matchingConfigs = (EGLConfig*) malloc(numberConfigs * sizeof(EGLConfig));
if (EGL_FALSE == eglChooseConfig(eglDisplay, config_attributes, matchingConfigs, numberConfigs, &numberConfigs))
{
printf("eglChooseConfig EROR\n");
if(matchingConfigs!=NULL)
{
フリー(matchingConfigs);
matchingConfigs=NULLです。
}
return -1;
}
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
EGLint display_attributes[] =
{
EGL_WIDTH、 DISPLAY_WIDTH、
EGL_HEIGHT、 DISPLAY_HEIGHT、
EGL_NONE };
/*ウィンドウ属性*/
EGLint window_attribList[] =
{
EGL_NONE
};
EGLNativeDisplayType eglNativeDisplayType = fbGetDisplay(0);
EGLNativeWindowType eglNativeWindow = fbCreateWindow(eglNativeDisplayType,
0、
0、
DISPLAY_WIDTH、
DISPLAY_HEIGHT);
eglSurface = eglCreateWindowSurface(eglDisplay,matchingConfigs[0],eglNativeWindow,window_attribList);
if (eglSurface == EGL_NO_SURFACE)
{
printf("eglSurface = %x\n", eglGetError());
}
const EGLint attribListCtx[] =
{
EGL_KHR_create_contextが必要です
EGL_CONTEXT_CLIENT_VERSION、2、
EGL_NONE
};
eglContext = eglCreateContext(eglDisplay, matchingConfigs[0], EGL_NO_CONTEXT, attribListCtx);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if (eglContext == EGL_NO_CONTEXT)
{
printf("eglContext = %x\n", eglGetError());
return -1;
}
cairo_device_t* cdt = cairo_egl_device_create(eglDisplay, eglContext);
eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
cairo_surface_t *surface = cairo_gl_surface_create_for_egl(cdt, eglSurface,
DISPLAY_WIDTH,DISPLAY_HEIGHT);
cairo_t *cr = nullptr;
cr = cairo_create(表面);
if(!cr)
{
printf("間違ったcairo_t!\n");
return -1;
}
//*********************************************************************************************
for (int index = 0; index < 1; ++index) {
cairo_set_source_rgb (cr, 0, 0, 0);
cairo_move_to (cr, 0, 0);
cairo_line_to(CR、200、200);
cairo_move_to (cr, 200, 0);
cairo_line_to (cr, 0, 200);
cairo_set_line_width (cr, 1);
cairo_stroke (CR);
cairo_rectangle (cr, 0, 0, 100,100);
cairo_set_source_rgba (cr, 1, 0, 0, 0.8);
cairo_fill (CR);
cairo_rectangle (cr, 0, 100, 100, 100);
cairo_set_source_rgba (cr, 0, 1, 0, 0.60);
cairo_fill (CR);
cairo_rectangle (cr, 100, 0, 100, 100);
cairo_set_source_rgba (cr, 0, 0, 1, 0.40);
cairo_fill (CR);
cairo_rectangle (cr, 100, 100, 100, 100);
cairo_set_source_rgba (cr, 1, 1, 0, 0.20);
cairo_fill (CR);
cairo_surface_flush(表面);
eglSwapBuffers(eglDisplay,eglSurface);
}
カイロが表面から写真を作成できることを確認するために、PNGファイルを作成しました
cairo_status_t s = cairo_surface_write_to_png(表面, "surface.png");
カイロで作った写真です【OK】
cairo_destroy(cr);
if (CAIRO_STATUS_SUCCESS == s)
{
printf("ステータス = OK \n");
}
else
{
printf("ステータス = エラー
}
if(matchingConfigs!=NULL)
{
フリー(matchingConfigs);
matchingConfigs=NULLです。
}
cairo_surface_destroy(表面);
printf("終了!\n");
return 0;
}
GPUを使用しているアプリケーションを確認する方法:
あなたが見ているなら https://community.nxp.com/thread/324670グラフィカルアプリケーションをプロファイリングして、GPUを使用しているかどうかを調査したり、vAnalyzerでパフォーマンスを測定してアプリケーションを分析したりできます。
私が言及したリンクによると、ubootで galcore.gpuProfiler = 1 を設定し、 /sys/module/galcore/parameters/gpuProfiler ファイルを確認する(cat、vi、nanoなどでファイルを読み取ります)出力が1の場合、すべてのことは正しい方法で行われます最後のステップは、いくつかの環境変数をエクスポートすることです。
export VIV_PROFILE=1
エクスポート VP_OUTPUT=sample.vpd
export VP_FRAME_NUM=1000
export VP_SYNC_MODE=1
VIV_PROFILE[0,1,2,3], VP_OUTPUT[any string], VP_FRAME_NUM[1,N], VP_SYNC_MODE[0,1]
注:VIV_PROFILE[0]vProfilerを無効にする(デフォルト)、VIV_PROFILE[1]vProfilerを有効にする、VIV_PROFILE[2]アプリケーション呼び出しによる制御、VIV_PROFILE[3]vProfilerでプロファイルするフレームをVP_FRAME_STARTとVP_FRAME_ENDで制御できます。
アプリケーションがGPUを使用している場合、smaple.vpdファイルが作成され、そうでない場合はvpdファイルがありません。