「App:Library:LVGL:docs:Porting:Add custom GPU」の版間の差分

提供: robot-jp wiki
ナビゲーションに移動検索に移動
 
(同じ利用者による、間の4版が非表示)
14行目: 14行目:
 
これをフックして、GPUでレンダリングを実行したり、組み込みのソフトウェアレンダラーを完全に置き換えたりすることができます。
 
これをフックして、GPUでレンダリングを実行したり、組み込みのソフトウェアレンダラーを完全に置き換えたりすることができます。
 
|}
 
|}
:[[App:Library:LVGL:docs:Porting|戻る : Previous]]
+
:[[App:Library:LVGL:docs:Porting#Add custom GPU|戻る : Previous]]
  
 
== Draw context ==
 
== Draw context ==
22行目: 22行目:
 
|-
 
|-
 
|
 
|
The core structure of drawing is <code>'''lv_draw_ctx_t'''</code>.  
+
The core structure of drawing is <code style="color: #bb0000;">'''lv_draw_ctx_t'''</code>.  
  
 
It contains a pointer to a buffer where drawing should happen and a couple of callbacks to draw rectangles, texts, and other primitives.
 
It contains a pointer to a buffer where drawing should happen and a couple of callbacks to draw rectangles, texts, and other primitives.
|描画のコア構造体は <code>'''lv_draw_ctx_t'''</code> です。
+
|描画のコア構造体は <code style="color: #bb0000;">'''lv_draw_ctx_t'''</code> です。
 
これには、描画が行われるバッファへのポインタと、長方形、テキスト、およびその他のプリミティブを描画するための2つのコールバックが含まれています。
 
これには、描画が行われるバッファへのポインタと、長方形、テキスト、およびその他のプリミティブを描画するための2つのコールバックが含まれています。
 
|}
 
|}
:[[App:Library:LVGL:docs:Porting|戻る : Previous]]
+
:[[App:Library:LVGL:docs:Porting#Add custom GPU|戻る : Previous]]
  
 
=== Fields ===
 
=== Fields ===
36行目: 36行目:
 
|-
 
|-
 
|
 
|
<code>'''lv_draw_ctx_t'''</code> has the following fields:
+
<code style="color: #bb0000;">'''lv_draw_ctx_t'''</code> has the following fields:
  
*<code>void * buf</code> Pointer to a buffer to draw into
+
*<code style="color: #bb0000;">void * buf</code> Pointer to a buffer to draw into
* <code>lv_area_t * buf_area</code> The position and size of <code>buf</code> (absolute coordinates)
+
* <code style="color: #bb0000;">lv_area_t * buf_area</code> The position and size of <code style="color: #bb0000;">buf</code> (absolute coordinates)
* <code>const lv_area_t * clip_area</code> The current clip area with absolute coordinates, always the same or smaller than <code>buf_area</code>. All drawings should be clipped to this area.
+
* <code style="color: #bb0000;">const lv_area_t * clip_area</code> The current clip area with absolute coordinates, always the same or smaller than <code style="color: #bb0000;">buf_area</code>. All drawings should be clipped to this area.
*<code>void (*draw_rect)()</code> Draw a rectangle with shadow, gradient, border, etc.
+
*<code style="color: #bb0000;">void (*draw_rect)()</code> Draw a rectangle with shadow, gradient, border, etc.
*<code>void (*draw_arc)()</code> Draw an arc
+
*<code style="color: #bb0000;">void (*draw_arc)()</code> Draw an arc
*<code>void (*draw_img_decoded)()</code> Draw an (A)RGB image that is already decoded by LVGL.
+
*<code style="color: #bb0000;">void (*draw_img_decoded)()</code> Draw an (A)RGB image that is already decoded by LVGL.
*<code>lv_res_t (*draw_img)()</code> Draw an image before decoding it (it bypasses LVGL's internal image decoders)
+
*<code style="color: #bb0000;">lv_res_t (*draw_img)()</code> Draw an image before decoding it (it bypasses LVGL's internal image decoders)
*<code>void (*draw_letter)()</code> Draw a letter
+
*<code style="color: #bb0000;">void (*draw_letter)()</code> Draw a letter
*<code>void (*draw_line)()</code> Draw a line
+
*<code style="color: #bb0000;">void (*draw_line)()</code> Draw a line
*<code>void (*draw_polygon)()</code> Draw a polygon
+
*<code style="color: #bb0000;">void (*draw_polygon)()</code> Draw a polygon
*<code>void (*draw_bg)()</code> Replace the buffer with a rect without decoration like radius or borders.
+
*<code style="color: #bb0000;">void (*draw_bg)()</code> Replace the buffer with a rect without decoration like radius or borders.
*<code>void (*wait_for_finish)()</code> Wait until all background operation are finished. (E.g. GPU operations)
+
*<code style="color: #bb0000;">void (*wait_for_finish)()</code> Wait until all background operation are finished. (E.g. GPU operations)
*<code>void * user_data</code> Custom user data for arbitrary purpose
+
*<code style="color: #bb0000;">void * user_data</code> Custom user data for arbitrary purpose
  
 
(For the sake of simplicity the parameters of the callbacks are not shown here.)
 
(For the sake of simplicity the parameters of the callbacks are not shown here.)
  
All <code>draw_*</code> callbacks receive a pointer to the current <code>draw_ctx</code> as their first parameter.  
+
All <code style="color: #bb0000;">draw_*</code> callbacks receive a pointer to the current <code style="color: #bb0000;">draw_ctx</code> as their first parameter.  
  
Among the other parameters there is a descriptor that tells what to draw, e.g. for <code>draw_rect</code> it's called lv_draw_rect_dsc_t, for <code>lv_draw_line</code> it's called lv_draw_line_dsc_t, etc.
+
Among the other parameters there is a descriptor that tells what to draw, e.g. for <code style="color: #bb0000;">draw_rect</code> it's called lv_draw_rect_dsc_t, for <code style="color: #bb0000;">lv_draw_line</code> it's called lv_draw_line_dsc_t, etc.
  
To correctly render according to a <code>draw_dsc</code> you need to be familiar with the Boxing model of LVGL and the meanings of the fields.  
+
To correctly render according to a <code style="color: #bb0000;">draw_dsc</code> you need to be familiar with the Boxing model of LVGL and the meanings of the fields.  
  
 
The name and meaning of the fields are identical to name and meaning of the Style properties.
 
The name and meaning of the fields are identical to name and meaning of the Style properties.
|<code>'''lv_draw_ctx_t'''</code> には次のフィールドがあります。
+
|<code style="color: #bb0000;">'''lv_draw_ctx_t'''</code> には次のフィールドがあります。
  
*<code>'''void * buf'''</code> 引き込むバッファへのポインタ
+
*<code style="color: #bb0000;">'''void * buf'''</code> 引き込むバッファへのポインタ
* <code>'''lv_area_t * buf_area'''</code>  (絶対座標)<code>'''buf'''</code>の位置とサイズ
+
* <code style="color: #bb0000;">'''lv_area_t * buf_area'''</code>  (絶対座標)<code style="color: #bb0000;">'''buf'''</code>の位置とサイズ
* <code>const lv_area_t * clip_area</code> 絶対座標を持つ現在のクリップ領域、常に <code>buf_area</code> と同じか、それより小さくなります。すべての図面はこの領域にクリップする必要があります。
+
* <code style="color: #bb0000;">const lv_area_t * clip_area</code> 絶対座標を持つ現在のクリップ領域、常に <code style="color: #bb0000;">buf_area</code> と同じか、それより小さくなります。すべての図面はこの領域にクリップする必要があります。
*<code>'''void (*draw_rect)()'''</code> 影,グラデーション,境界線などで長方形を描く。
+
*<code style="color: #bb0000;">'''void (*draw_rect)()'''</code> 影,グラデーション,境界線などで長方形を描く。
*<code>'''void (*draw_arc)()'''</code> 円弧を描く。
+
*<code style="color: #bb0000;">'''void (*draw_arc)()'''</code> 円弧を描く。
*<code>'''void (*draw_img_decoded)()'''</code> LVGLによってすでにデコードされている (A)RGB画像 を描画します。
+
*<code style="color: #bb0000;">'''void (*draw_img_decoded)()'''</code> LVGLによってすでにデコードされている (A)RGB画像 を描画します。
*<code>'''lv_res_t (*draw_img)()'''</code> デコードする前に画像を描画します(LVGLの内部画像デコーダーをバイパスします)
+
*<code style="color: #bb0000;">'''lv_res_t (*draw_img)()'''</code> デコードする前に画像を描画します(LVGLの内部画像デコーダーをバイパスします)
*<code>'''void (*draw_letter)()'''</code>  文字を描く
+
*<code style="color: #bb0000;">'''void (*draw_letter)()'''</code>  文字を描く
*<code>'''void (*draw_line)()'''</code> 線を引く
+
*<code style="color: #bb0000;">'''void (*draw_line)()'''</code> 線を引く
*<code>'''void (*draw_polygon)()'''</code>  折れ線を描く
+
*<code style="color: #bb0000;">'''void (*draw_polygon)()'''</code>  折れ線を描く
*<code>'''void (*draw_bg)()'''</code> バッファを、半径や境界線などの装飾のない長方形に置き換えます。
+
*<code style="color: #bb0000;">'''void (*draw_bg)()'''</code> バッファを、半径や境界線などの装飾のない長方形に置き換えます。
*<code>'''void (*wait_for_finish)()'''</code>すべてのバックグラウンド操作が終了するまで待ちます。(GPU操作など)
+
*<code style="color: #bb0000;">'''void (*wait_for_finish)()'''</code>すべてのバックグラウンド操作が終了するまで待ちます。(GPU操作など)
*<code>'''void * user_data'''</code> 任意の目的のためのカスタムユーザーデータ
+
*<code style="color: #bb0000;">'''void * user_data'''</code> 任意の目的のためのカスタムユーザーデータ
  
 
(簡単にするために、コールバックのパラメーターはここには示されていません。)
 
(簡単にするために、コールバックのパラメーターはここには示されていません。)
  
  
すべての<code>'''draw_*'''</code>コールバックは、最初のパラメーターとして現在へのポインター<code>'''draw_ctx'''</code>を受け取ります。
+
すべての<code style="color: #bb0000;">'''draw_*'''</code>コールバックは、最初のパラメーターとして現在へのポインター<code style="color: #bb0000;">'''draw_ctx'''</code>を受け取ります。
  
他のパラメータの中には、何を描画するかを指示する記述子があります。たとえば、 <code>'''draw_rect'''</code> は '''lv_draw_rect_dsc_t''' から呼ばれて、<code>'''lv_draw_line'''</code> は '''lv_draw_line_dsc_t''' から呼ばれます。
+
他のパラメータの中には、何を描画するかを指示する記述子があります。たとえば、 <code style="color: #bb0000;">'''draw_rect'''</code> は '''lv_draw_rect_dsc_t''' から呼ばれて、<code style="color: #bb0000;">'''lv_draw_line'''</code> は '''lv_draw_line_dsc_t''' から呼ばれます。
  
<code>'''draw_dsc'''</code> に従って正しくレンダリングするには、LVGLの枠型モデルとフィールドの意味に精通している必要があります。
+
<code style="color: #bb0000;">'''draw_dsc'''</code> に従って正しくレンダリングするには、LVGLの枠型モデルとフィールドの意味に精通している必要があります。
  
 
フィールドの名前と意味は、Styleプロパティの名前と同じ意味です。
 
フィールドの名前と意味は、Styleプロパティの名前と同じ意味です。
 
|}
 
|}
:[[App:Library:LVGL:docs:Porting|戻る : Previous]]
+
:[[App:Library:LVGL:docs:Porting#Add custom GPU|戻る : Previous]]
  
 
=== Initialization ===
 
=== Initialization ===
96行目: 96行目:
 
|-
 
|-
 
|
 
|
The <code>lv_disp_drv_t</code> has 4 fields related to the draw context:
+
The <code style="color: #bb0000;">lv_disp_drv_t</code> has 4 fields related to the draw context:
  
*<code>lv_draw_ctx_t * draw_ctx</code> Pointer to the <code>draw_ctx</code> of this display
+
*<code style="color: #bb0000;">lv_draw_ctx_t * draw_ctx</code> Pointer to the <code style="color: #bb0000;">draw_ctx</code> of this display
* <code>'''void (*draw_ctx_init)(struct _lv_disp_drv_t * disp_drv, lv_draw_ctx_t * draw_ctx)'''</code> Callback to initialize a <code>'''draw_ctx'''</code>
+
* <code style="color: #bb0000;">'''void (*draw_ctx_init)(struct _lv_disp_drv_t * disp_drv, lv_draw_ctx_t * draw_ctx)'''</code> Callback to initialize a <code style="color: #bb0000;">'''draw_ctx'''</code>
* <code>'''void (*draw_ctx_deinit)(struct _lv_disp_drv_t * disp_drv, lv_draw_ctx_t * draw_ctx)'''</code> Callback to de-initialize a <code>'''draw_ctx'''</code>
+
* <code style="color: #bb0000;">'''void (*draw_ctx_deinit)(struct _lv_disp_drv_t * disp_drv, lv_draw_ctx_t * draw_ctx)'''</code> Callback to de-initialize a <code style="color: #bb0000;">'''draw_ctx'''</code>
* <code>size_t draw_ctx_size</code> Size of the draw context structure. E.g. <code>sizeof'''(lv_draw_sw_ctx_t)'''</code>
+
* <code style="color: #bb0000;">size_t draw_ctx_size</code> Size of the draw context structure. E.g. <code style="color: #bb0000;">sizeof'''(lv_draw_sw_ctx_t)'''</code>
  
When you ignore these fields, LVGL will set default values for callbacks and size in <code>lv_disp_drv_init()</code> based on the configuration in <code>lv_conf.h</code>.  
+
When you ignore these fields, LVGL will set default values for callbacks and size in <code style="color: #bb0000;">lv_disp_drv_init()</code> based on the configuration in <code style="color: #bb0000;">lv_conf.h</code>.  
  
  
<code>'''lv_disp_drv_register()'''</code> will allocate a <code>'''draw_ctx'''</code> based on <code>'''draw_ctx_size'''</code> and call <code>'''draw_ctx_init()'''</code> on it.
+
<code style="color: #bb0000;">'''lv_disp_drv_register()'''</code> will allocate a <code style="color: #bb0000;">'''draw_ctx'''</code> based on <code style="color: #bb0000;">'''draw_ctx_size'''</code> and call <code style="color: #bb0000;">'''draw_ctx_init()'''</code> on it.
  
However, you can overwrite the callbacks and the size values before calling <code>'''lv_disp_drv_register()'''</code>.  
+
However, you can overwrite the callbacks and the size values before calling <code style="color: #bb0000;">'''lv_disp_drv_register()'''</code>.  
  
It makes it possible to use your own <code>'''draw_ctx'''</code> with your own callbacks.
+
It makes it possible to use your own <code style="color: #bb0000;">'''draw_ctx'''</code> with your own callbacks.
|<code>lv_disp_drv_t</code> には、描画コンテキストに関連する4つのフィールドがあります。
+
|<code style="color: #bb0000;">lv_disp_drv_t</code> には、描画コンテキストに関連する4つのフィールドがあります。
  
*<code>lv_draw_ctx_t * draw_ctx</code> : このディスプレイの <code>'''draw_ctx'''</code> へのポインタ
+
*<code style="color: #bb0000;">lv_draw_ctx_t * draw_ctx</code> : このディスプレイの <code style="color: #bb0000;">'''draw_ctx'''</code> へのポインタ
* <code>'''void (*draw_ctx_init)(struct _lv_disp_drv_t * disp_drv, lv_draw_ctx_t * draw_ctx)'''</code> : <code>draw_ctx</code> を初期化するためのコールバック
+
* <code style="color: #bb0000;">'''void (*draw_ctx_init)(struct _lv_disp_drv_t * disp_drv, lv_draw_ctx_t * draw_ctx)'''</code> : <code style="color: #bb0000;">draw_ctx</code> を初期化するためのコールバック
* <code>'''void (*draw_ctx_deinit)(struct _lv_disp_drv_t * disp_drv, lv_draw_ctx_t * draw_ctx)'''</code> : <code>'''draw_ctx'''</code>の初期化を解除するためのコールバック
+
* <code style="color: #bb0000;">'''void (*draw_ctx_deinit)(struct _lv_disp_drv_t * disp_drv, lv_draw_ctx_t * draw_ctx)'''</code> : <code style="color: #bb0000;">'''draw_ctx'''</code>の初期化を解除するためのコールバック
* <code>'''size_t draw_ctx_size'''</code> : 描画コンテキスト構造のサイズ。例えば<code>'''sizeof(lv_draw_sw_ctx_t)'''</code>
+
* <code style="color: #bb0000;">'''size_t draw_ctx_size'''</code> : 描画コンテキスト構造のサイズ。例えば<code style="color: #bb0000;">'''sizeof(lv_draw_sw_ctx_t)'''</code>
  
これらのフィールドを無視した場合、LVGLは <code>'''lv_conf.h'''</code> の configuration に基づき <code>'''lv_disp_drv_init()'''</code> にコールバックとサイズのデフォルト値を設定します。
+
これらのフィールドを無視した場合、LVGLは <code style="color: #bb0000;">'''lv_conf.h'''</code> の configuration に基づき <code style="color: #bb0000;">'''lv_disp_drv_init()'''</code> にコールバックとサイズのデフォルト値を設定します。
  
  
<code>'''lv_disp_drv_register()'''</code>は <code>'''draw_ctx_size'''</code> に基づいて <code>'''draw_ctx'''</code> を割り当て、その上で  <code>'''draw_ctx_init()'''</code> を呼び出します。
+
<code style="color: #bb0000;">'''lv_disp_drv_register()'''</code>は <code style="color: #bb0000;">'''draw_ctx_size'''</code> に基づいて <code style="color: #bb0000;">'''draw_ctx'''</code> を割り当て、その上で  <code style="color: #bb0000;">'''draw_ctx_init()'''</code> を呼び出します。
  
ただし、を呼び出す前に、コールバックとサイズの値を上書きできます<code>'''lv_disp_drv_register()'''</code>。
+
ただし、を呼び出す前に、コールバックとサイズの値を上書きできます<code style="color: #bb0000;">'''lv_disp_drv_register()'''</code>。
  
それはあなた自身のコールバックで、あなた自身である <code>'''draw_ctx'''</code> を使うことを可能にします。
+
それはあなた自身のコールバックで、あなた自身である <code style="color: #bb0000;">'''draw_ctx'''</code> を使うことを可能にします。
 
|}
 
|}
:[[App:Library:LVGL:docs:Porting|戻る : Previous]]
+
:[[App:Library:LVGL:docs:Porting#Add custom GPU|戻る : Previous]]
  
 
== Software renderer ==
 
== Software renderer ==
135行目: 135行目:
 
|-
 
|-
 
|
 
|
LVGL's built in software renderer extends the basic <code>lv_draw_ctx_t</code> structure and sets the draw callbacks. It looks like this:
+
LVGL's built in software renderer extends the basic <code style="color: #bb0000;">lv_draw_ctx_t</code> structure and sets the draw callbacks. It looks like this:
 
<syntaxhighlight lang="C++" style="border: 1px dashed gray;">
 
<syntaxhighlight lang="C++" style="border: 1px dashed gray;">
 
  typedef struct {
 
  typedef struct {
145行目: 145行目:
 
  } lv_draw_sw_ctx_t;
 
  } lv_draw_sw_ctx_t;
 
</syntaxhighlight>
 
</syntaxhighlight>
Set the draw callbacks in <code>draw_ctx_init()</code> like:
+
Set the draw callbacks in <code style="color: #bb0000;">draw_ctx_init()</code> like:
 
<syntaxhighlight lang="C++" style="border: 1px dashed gray;">
 
<syntaxhighlight lang="C++" style="border: 1px dashed gray;">
 
  draw_sw_ctx->base_draw.draw_rect = lv_draw_sw_rect;
 
  draw_sw_ctx->base_draw.draw_rect = lv_draw_sw_rect;
154行目: 154行目:
  
  
LVGLに組み込まれているソフトウェアレンダラーは、基本の<code>lv_draw_ctx_t</code>構造体を拡張し、描画コールバックを設定します。次のようになります。
+
LVGLに組み込まれているソフトウェアレンダラーは、基本の構造体<code style="color: #bb0000;">lv_draw_ctx_t</code>を拡張し、描画コールバックを設定します。次のようになります。
 
<syntaxhighlight lang="C++" style="border: 1px dashed gray;">
 
<syntaxhighlight lang="C++" style="border: 1px dashed gray;">
 
  '''typedef struct {
 
  '''typedef struct {
164行目: 164行目:
 
  } lv_draw_sw_ctx_t;'''
 
  } lv_draw_sw_ctx_t;'''
 
</syntaxhighlight>
 
</syntaxhighlight>
<code>'''draw_ctx_init()'''</code>次のよう に描画コールバックを設定します。
+
<code style="color: #bb0000;">'''draw_ctx_init()'''</code>の中では次のよう に描画コールバックを設定します。
 
<syntaxhighlight lang="C++" style="border: 1px dashed gray;">
 
<syntaxhighlight lang="C++" style="border: 1px dashed gray;">
 
  '''draw_sw_ctx-> base_draw.draw_rect = lv_draw_sw_rect;
 
  '''draw_sw_ctx-> base_draw.draw_rect = lv_draw_sw_rect;
171行目: 171行目:
 
</syntaxhighlight>
 
</syntaxhighlight>
 
|}
 
|}
:[[App:Library:LVGL:docs:Porting|戻る : Previous]]
+
:[[App:Library:LVGL:docs:Porting#Add custom GPU|戻る : Previous]]
  
 
=== Blend callback ===
 
=== Blend callback ===
179行目: 179行目:
 
|-
 
|-
 
|
 
|
As you saw above the software renderer adds the <code>blend</code> callback field. It's a special callback related to how the software renderer works. All draw operations end up in the <code>blend</code> callback which can either fill an area or copy an image to an area by considering an optional mask.
+
As you saw above the software renderer adds the <code style="color: #bb0000;">blend</code> callback field. It's a special callback related to how the software renderer works. All draw operations end up in the <code style="color: #bb0000;">blend</code> callback which can either fill an area or copy an image to an area by considering an optional mask.
  
The <code>lv_draw_sw_blend_dsc_t</code> parameter describes what and how to blend. It has the following fields:
+
The <code style="color: #bb0000;">lv_draw_sw_blend_dsc_t</code> parameter describes what and how to blend. It has the following fields:
  
* <code>const lv_area_t * blend_area</code> The area with absolute coordinates to draw on <code>draw_ctx->buf</code>. If <code>src_buf</code> is set, it's the coordinates of the image to blend.
+
* <code style="color: #bb0000;">const lv_area_t * blend_area</code> The area with absolute coordinates to draw on <code style="color: #bb0000;">draw_ctx->buf</code>. If <code style="color: #bb0000;">src_buf</code> is set, it's the coordinates of the image to blend.
* <code>const lv_color_t * src_buf</code> Pointer to an image to blend. If set, <code>color</code> is ignored. If not set fill <code>blend_area</code> with <code>color</code>
+
* <code style="color: #bb0000;">const lv_color_t * src_buf</code> Pointer to an image to blend. If set, <code style="color: #bb0000;">color</code> is ignored. If not set fill <code style="color: #bb0000;">blend_area</code> with <code style="color: #bb0000;">color</code>
* <code>lv_color_t color</code> Fill color. Used only if <code>src_buf == NULL</code>
+
* <code style="color: #bb0000;">lv_color_t color</code> Fill color. Used only if <code style="color: #bb0000;">src_buf == NULL</code>
* <code>lv_opa_t * mask_buf</code> NULL if ignored, or an alpha mask to apply on <code>blend_area</code>
+
* <code style="color: #bb0000;">lv_opa_t * mask_buf</code> NULL if ignored, or an alpha mask to apply on <code style="color: #bb0000;">blend_area</code>
* <code>lv_draw_mask_res_t mask_res</code> The result of the previous mask operation. (<code>LV_DRAW_MASK_RES_...</code>)
+
* <code style="color: #bb0000;">lv_draw_mask_res_t mask_res</code> The result of the previous mask operation. (<code style="color: #bb0000;">LV_DRAW_MASK_RES_...</code>)
* <code>const lv_area_t * mask_area</code> The area of <code>mask_buf</code> with absolute coordinates
+
* <code style="color: #bb0000;">const lv_area_t * mask_area</code> The area of <code style="color: #bb0000;">mask_buf</code> with absolute coordinates
* <code>lv_opa_t opa</code> The overall opacity
+
* <code style="color: #bb0000;">lv_opa_t opa</code> The overall opacity
* <code>lv_blend_mode_t blend_mode</code> E.g. <code>LV_BLEND_MODE_ADDITIVE</code>
+
* <code style="color: #bb0000;">lv_blend_mode_t blend_mode</code> E.g. <code style="color: #bb0000;">LV_BLEND_MODE_ADDITIVE</code>
|上で見たように、ソフトウェアレンダラーは<code>blend</code>コールバックフィールドを追加します。これは、ソフトウェアレンダラーの動作に関連する特別なコールバックです。すべての描画操作は<code>blend</code>コールバックで終了します。コールバックは、オプションのマスクを考慮して、領域を塗りつぶすか、画像を領域にコピーすることができます。
+
|上で見たように、ソフトウェアレンダラーは<code style="color: #bb0000;">blend</code>コールバックフィールドを追加します。これは、ソフトウェアレンダラーの動作に関連する特別なコールバックです。すべての描画操作は<code style="color: #bb0000;">blend</code>コールバックで終了します。コールバックは、オプションのマスクを考慮して、領域を塗りつぶすか、画像を領域にコピーすることができます。
  
この<code>lv_draw_sw_blend_dsc_t</code> パラメータは、何をどのようにブレンドするかを記述します。次のフィールドがあります。
+
この パラメータ<code style="color: #bb0000;">lv_draw_sw_blend_dsc_t</code>は、何をどのようにブレンドするかを記述します。次のフィールドがあります。
  
* <code>const lv_area_t * blend_area</code> 描画する絶対座標を持つ領域 <code>draw_ctx->buf</code> 。が設定されている場合<code>src_buf</code>、ブレンドする画像の座標です。
+
*<code style="color: #bb0000;">const lv_area_t * blend_area</code> <code style="color: #bb0000;">draw_ctx->buf</code>を描画する絶対座標を持つ領域  。<code style="color: #bb0000;">src_buf</code>が設定されている場合、ブレンドする画像の座標です。
* <code>const lv_color_t * src_buf</code> ブレンドする画像へのポインタ。設定されて <code>color</code> いる場合、無視されます。設定されていない場合は<code>blend_area</code><code>color</code>
+
* <code style="color: #bb0000;">const lv_color_t * src_buf</code> ブレンドする画像へのポインタ。設定されている場合、<code style="color: #bb0000;">color</code>は無視されます。設定されていない場合、<code style="color: #bb0000;">color</code><code style="color: #bb0000;">blend_area</code>を塗りつぶします。
* <code>lv_color_t color</code> 塗りつぶしの色。次の場合にのみ使用されます<code>src_buf == NULL</code>
+
* <code style="color: #bb0000;">lv_color_t color</code> 塗りつぶしの色。<code style="color: #bb0000;">src_buf == NULL</code>の場合にのみ使用されます
* <code>lv_opa_t * mask_buf</code> 無視された場合はNULL、または適用するアルファマスク<code>blend_area</code>
+
* <code style="color: #bb0000;">lv_opa_t * mask_buf</code> 無視された場合はNULL、または<code style="color: #bb0000;">blend_area</code>に適用するアルファマスク
* <code>lv_draw_mask_res_t mask_res</code> 前のマスク操作の結果。( <code>LV_DRAW_MASK_RES_...</code> )
+
* <code style="color: #bb0000;">lv_draw_mask_res_t mask_res</code> 前のマスク操作の結果。( <code style="color: #bb0000;">LV_DRAW_MASK_RES_...</code> )
* <code>const lv_area_t * mask_area</code> LVGLには、柔軟で拡張可能な描画パイプラインがあります。 <code>mask_buf</code> 絶対座標のある領域
+
* <code style="color: #bb0000;">const lv_area_t * mask_area</code> <code style="color: #bb0000;">mask_buf</code> 絶対座標のある領域
* <code>lv_opa_t opa</code> 全体的な不透明度
+
* <code style="color: #bb0000;">lv_opa_t opa</code> 全体的な不透明度
* <code>lv_blend_mode_t blend_mode</code> 例えば <code>LV_BLEND_MODE_ADDITIVE</code>
+
* <code style="color: #bb0000;">lv_blend_mode_t blend_mode</code> 例えば <code style="color: #bb0000;">LV_BLEND_MODE_ADDITIVE</code>
 
|}
 
|}
:[[App:Library:LVGL:docs:Porting|戻る : Previous]]
+
:[[App:Library:LVGL:docs:Porting#Add custom GPU|戻る : Previous]]
  
 
== Extend the software renderer ==
 
== Extend the software renderer ==
216行目: 216行目:
 
Let's take a practical example: you would like to use your MCUs GPU for color fill operations only.
 
Let's take a practical example: you would like to use your MCUs GPU for color fill operations only.
  
As all draw callbacks call <code>blend</code> callback to fill an area in the end only the <code>blend</code> callback needs to be overwritten.
+
As all draw callbacks call <code style="color: #bb0000;">blend</code> callback to fill an area in the end only the <code style="color: #bb0000;">blend</code> callback needs to be overwritten.
  
First extend <code>lv_draw_sw_ctx_t</code>:
+
First extend <code style="color: #bb0000;">lv_draw_sw_ctx_t</code>:
+
<syntaxhighlight lang="C++" style="border: 1px dashed gray;">
 
  /*We don't add new fields, so just for clarity add new type*/
 
  /*We don't add new fields, so just for clarity add new type*/
 
  typedef lv_draw_sw_ctx_t my_draw_ctx_t;
 
  typedef lv_draw_sw_ctx_t my_draw_ctx_t;
234行目: 234行目:
 
      my_draw_ctx->base_draw.wait_for_finish = my_gpu_wait;
 
      my_draw_ctx->base_draw.wait_for_finish = my_gpu_wait;
 
  }
 
  }
After calling <code>lv_disp_draw_init(&drv)</code> you can assign the new <code>draw_ctx_init</code> callback and set <code>draw_ctx_size</code> to overwrite the defaults:
+
</syntaxhighlight>
 +
 
 +
 
 +
After calling <code style="color: #bb0000;">lv_disp_draw_init(&drv)</code> you can assign the new <code style="color: #bb0000;">draw_ctx_init</code> callback and set <code style="color: #bb0000;">draw_ctx_size</code> to overwrite the defaults:
 +
<syntaxhighlight lang="C++" style="border: 1px dashed gray;">
 
  static lv_disp_drv_t drv;
 
  static lv_disp_drv_t drv;
 
  lv_disp_draw_init(&drv);
 
  lv_disp_draw_init(&drv);
246行目: 250行目:
 
   
 
   
 
  lv_disp_drv_register(&drv);
 
  lv_disp_drv_register(&drv);
This way when LVGL calls <code>blend</code> it will call <code>my_draw_blend</code> and we can do custom GPU operations. Here is a complete example:
+
</syntaxhighlight>
 +
 
 +
 
 +
This way when LVGL calls <code style="color: #bb0000;">blend</code> it will call <code style="color: #bb0000;">my_draw_blend</code> and we can do custom GPU operations.  
 +
 
 +
Here is a complete example:
 +
<syntaxhighlight lang="C++" style="border: 1px dashed gray;">
 
  void my_draw_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend_dsc_t * dsc)
 
  void my_draw_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend_dsc_t * dsc)
 
  {
 
  {
273行目: 283行目:
 
      }
 
      }
 
  }
 
  }
 +
</syntaxhighlight>
 +
 +
 
The implementation of wait callback is much simpler:
 
The implementation of wait callback is much simpler:
 +
<syntaxhighlight lang="C++" style="border: 1px dashed gray;">
 
  void my_gpu_wait(lv_draw_ctx_t * draw_ctx)
 
  void my_gpu_wait(lv_draw_ctx_t * draw_ctx)
 
  {
 
  {
281行目: 295行目:
 
      lv_draw_sw_wait_for_finish(draw_ctx);
 
      lv_draw_sw_wait_for_finish(draw_ctx);
 
  }
 
  }
 +
</syntaxhighlight>
 
|
 
|
 +
実際の例を見てみましょう。MCUGPUをカラーフィル操作にのみ使用したいとします。
  
  
実際の例を見てみましょう。MCUGPUをカラーフィル操作にのみ使用したいとします。
+
すべての描画コールバックはコールバック<code style="color: #bb0000;">blend</code>を呼び出して最終的に領域を埋めるため、<code style="color: #bb0000;">blend</code>コールバックのみを上書きする必要があります。
  
すべての描画コールバックはコールバックを呼び出し<code>blend</code>て最終的に領域を埋めるため、<code>blend</code>コールバックのみを上書きする必要があります。
+
最初の拡張<code style="color: #bb0000;">lv_draw_sw_ctx_t</code>
 
+
<syntaxhighlight lang="C++" style="border: 1px dashed gray;">
最初の拡張<code>lv_draw_sw_ctx_t</code>:
 
 
  / *新しいフィールドは追加しないため、わかりやすくするために新しいタイプを追加します* /
 
  / *新しいフィールドは追加しないため、わかりやすくするために新しいタイプを追加します* /
 
  typedef lv_draw_sw_ctx_t my_draw_ctx_t;
 
  typedef lv_draw_sw_ctx_t my_draw_ctx_t;
303行目: 318行目:
 
      my_draw_ctx-> base_draw.wait_for_finish = my_gpu_wait;
 
      my_draw_ctx-> base_draw.wait_for_finish = my_gpu_wait;
 
  }
 
  }
呼び出した後、新しいコールバックを<code>lv_disp_draw_init(&drv)</code>割り当て、デフォルトを上書きするように 設定できます。<code>draw_ctx_initdraw_ctx_size</code>
+
</syntaxhighlight>
 +
<code style="color: #bb0000;">lv_disp_draw_init(&drv)</code>を呼び出した後、新しいコールバック<code style="color: #bb0000;">draw_ctx_initdraw_ctx_size</code>を割り当て、デフォルトを上書きするように 設定できます。
 +
<syntaxhighlight lang="C++" style="border: 1px dashed gray;">
 
  static lv_disp_drv_t drv;
 
  static lv_disp_drv_t drv;
 
  lv_disp_draw_init(&drv);
 
  lv_disp_draw_init(&drv);
315行目: 332行目:
 
   
 
   
 
  lv_disp_drv_register(&drv);
 
  lv_disp_drv_register(&drv);
このようにして、LVGLが<code>blend</code>呼び出すと、それが呼び出さ<code>my_draw_blend</code>れ、カスタムGPU操作を実行できます。完全な例を次に示します。
+
</syntaxhighlight>
 +
 
 +
 
 +
このようにして、LVGLが<code style="color: #bb0000;">blend</code>呼び出すと、<code style="color: #bb0000;">my_draw_blend</code>が呼び出され、カスタムGPU操作を実行できます。
 +
 
 +
完全な例を次に示します。
 +
<syntaxhighlight lang="C++" style="border: 1px dashed gray;">
 
  void my_draw_blend(lv_draw_ctx_t * draw_ctx、const lv_draw_sw_blend_dsc_t * dsc)
 
  void my_draw_blend(lv_draw_ctx_t * draw_ctx、const lv_draw_sw_blend_dsc_t * dsc)
 
  {
 
  {
342行目: 365行目:
 
      }
 
      }
 
  }
 
  }
 +
</syntaxhighlight>
 +
 +
 
待機コールバックの実装ははるかに簡単です。
 
待機コールバックの実装ははるかに簡単です。
 +
<syntaxhighlight lang="C++" style="border: 1px dashed gray;">
 
  void my_gpu_wait(lv_draw_ctx_t * draw_ctx)
 
  void my_gpu_wait(lv_draw_ctx_t * draw_ctx)
 
  {
 
  {
350行目: 377行目:
 
      lv_draw_sw_wait_for_finish(draw_ctx);
 
      lv_draw_sw_wait_for_finish(draw_ctx);
 
  }
 
  }
 +
</syntaxhighlight>
 
|}
 
|}
:[[App:Library:LVGL:docs:Porting|戻る : Previous]]
+
:[[App:Library:LVGL:docs:Porting#Add custom GPU|戻る : Previous]]
  
 
=== New rectangle drawer ===
 
=== New rectangle drawer ===
359行目: 387行目:
 
|-
 
|-
 
|
 
|
If your MCU has a more powerful GPU that can draw e.g. rounded rectangles you can replace the original software drawer too. A custom <code>draw_rect</code> callback might look like this:
+
If your MCU has a more powerful GPU that can draw e.g. rounded rectangles you can replace the original software drawer too. A custom <code style="color: #bb0000;">draw_rect</code> callback might look like this:
 +
<syntaxhighlight lang="C++" style="border: 1px dashed gray;">
 
  void my_draw_rect(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dsc, const lv_area_t * coords)
 
  void my_draw_rect(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dsc, const lv_area_t * coords)
 
  {
 
  {
383行目: 412行目:
 
    }
 
    }
 
  }
 
  }
<code>my_draw_rect</code> can fully bypass the use of <code>blend</code> callback if needed.
+
</syntaxhighlight>
|MCUに丸みを帯びた長方形などを描画できるより強力なGPUがある場合は、元のソフトウェアドロワーを置き換えることもできます。カスタム<code>draw_rect</code>コールバックは次のようになります。
+
<code style="color: #bb0000;">my_draw_rect</code> can fully bypass the use of <code style="color: #bb0000;">blend</code> callback if needed.
 +
|MCUに丸みを帯びた長方形などを描画できるより強力なGPUがある場合は、元のソフトウェアドロワーを置き換えることもできます。カスタム<code style="color: #bb0000;">draw_rect</code>コールバックは次のようになります。
 +
<syntaxhighlight lang="C++" style="border: 1px dashed gray;">
 
  void my_draw_rect(lv_draw_ctx_t * draw_ctx、const lv_draw_rect_dsc_t * dsc、const lv_area_t * coords)
 
  void my_draw_rect(lv_draw_ctx_t * draw_ctx、const lv_draw_rect_dsc_t * dsc、const lv_area_t * coords)
 
  {
 
  {
408行目: 439行目:
 
    }
 
    }
 
  }
 
  }
<code>my_draw_rectblend</code>必要に応じて、コールバック の使用を完全にバイパスできます。
+
</syntaxhighlight>
 +
必要に応じて、<code style="color: #bb0000;">my_draw_rectblend</code>は<code style="color: #bb0000;">blend</code> コールバック の使用を完全にバイパスできます。
 
|}
 
|}
:[[App:Library:LVGL:docs:Porting|戻る : Previous]]
+
:[[App:Library:LVGL:docs:Porting#Add custom GPU|戻る : Previous]]
  
 
== Fully custom draw engine ==
 
== Fully custom draw engine ==
418行目: 450行目:
 
|-
 
|-
 
|
 
|
For example if your MCU/MPU supports a powerful vector graphics engine you might use only that instead of LVGL's SW renderer. In this case, you need to base the renderer on the basic <code>lv_draw_ctx_t</code> (instead of <code>lv_draw_sw_ctx_t</code>) and extend/initialize it as you wish.
+
For example if your MCU/MPU supports a powerful vector graphics engine you might use only that instead of LVGL's SW renderer.  
|たとえば、MCU / MCUが強力なベクターグラフィックエンジンをサポートしている場合は、LVGLのSWレンダラーの代わりにそれだけを使用できます。<code>lv_draw_ctx_t</code>この場合、レンダラーを(ではなく)基本に基づいて、必要に応じて<code>lv_draw_sw_ctx_t</code>拡張/初期化する必要があります。
+
 
 +
 
 +
In this case, you need to base the renderer on the basic <code style="color: #bb0000;">lv_draw_ctx_t</code> (instead of <code style="color: #bb0000;">lv_draw_sw_ctx_t</code>) and extend/initialize it as you wish.
 +
|たとえば、MCU / MCUが強力なベクターグラフィックエンジンをサポートしている場合は、LVGLのSWレンダラーの代わりにそれだけを使用できます。
 +
 
 +
 
 +
この場合、基本に基づいて、(<code style="color: #bb0000;">lv_draw_sw_ctx_t</code>ではなく)<code style="color: #bb0000;">lv_draw_ctx_t</code>レンダラーを必要に応じて拡張/初期化する必要があります。
 
|}
 
|}
:[[App:Library:LVGL:docs:Porting|戻る : Previous]]
+
:[[App:Library:LVGL:docs:Porting#Add custom GPU|戻る : Previous]]

2022年8月18日 (木) 22:46時点における最新版

https://docs.lvgl.io/8.2/porting/gpu.html

Add custom GPU

英文 自動翻訳

LVGL has a flexible and extendable draw pipeline.

You can hook it to do some rendering with a GPU or even completely replace the built-in software renderer.

LVGLには、柔軟で拡張可能な描画パイプラインがあります。

これをフックして、GPUでレンダリングを実行したり、組み込みのソフトウェアレンダラーを完全に置き換えたりすることができます。

戻る : Previous

Draw context

英文 自動翻訳

The core structure of drawing is lv_draw_ctx_t.

It contains a pointer to a buffer where drawing should happen and a couple of callbacks to draw rectangles, texts, and other primitives.

描画のコア構造体は lv_draw_ctx_t です。

これには、描画が行われるバッファへのポインタと、長方形、テキスト、およびその他のプリミティブを描画するための2つのコールバックが含まれています。

戻る : Previous

Fields

英文 自動翻訳

lv_draw_ctx_t has the following fields:

  • void * buf Pointer to a buffer to draw into
  • lv_area_t * buf_area The position and size of buf (absolute coordinates)
  • const lv_area_t * clip_area The current clip area with absolute coordinates, always the same or smaller than buf_area. All drawings should be clipped to this area.
  • void (*draw_rect)() Draw a rectangle with shadow, gradient, border, etc.
  • void (*draw_arc)() Draw an arc
  • void (*draw_img_decoded)() Draw an (A)RGB image that is already decoded by LVGL.
  • lv_res_t (*draw_img)() Draw an image before decoding it (it bypasses LVGL's internal image decoders)
  • void (*draw_letter)() Draw a letter
  • void (*draw_line)() Draw a line
  • void (*draw_polygon)() Draw a polygon
  • void (*draw_bg)() Replace the buffer with a rect without decoration like radius or borders.
  • void (*wait_for_finish)() Wait until all background operation are finished. (E.g. GPU operations)
  • void * user_data Custom user data for arbitrary purpose

(For the sake of simplicity the parameters of the callbacks are not shown here.)

All draw_* callbacks receive a pointer to the current draw_ctx as their first parameter.

Among the other parameters there is a descriptor that tells what to draw, e.g. for draw_rect it's called lv_draw_rect_dsc_t, for lv_draw_line it's called lv_draw_line_dsc_t, etc.

To correctly render according to a draw_dsc you need to be familiar with the Boxing model of LVGL and the meanings of the fields.

The name and meaning of the fields are identical to name and meaning of the Style properties.

lv_draw_ctx_t には次のフィールドがあります。
  • void * buf 引き込むバッファへのポインタ
  • lv_area_t * buf_area (絶対座標)bufの位置とサイズ
  • const lv_area_t * clip_area 絶対座標を持つ現在のクリップ領域、常に buf_area と同じか、それより小さくなります。すべての図面はこの領域にクリップする必要があります。
  • void (*draw_rect)() 影,グラデーション,境界線などで長方形を描く。
  • void (*draw_arc)() 円弧を描く。
  • void (*draw_img_decoded)() LVGLによってすでにデコードされている (A)RGB画像 を描画します。
  • lv_res_t (*draw_img)() デコードする前に画像を描画します(LVGLの内部画像デコーダーをバイパスします)
  • void (*draw_letter)() 文字を描く
  • void (*draw_line)() 線を引く
  • void (*draw_polygon)() 折れ線を描く
  • void (*draw_bg)() バッファを、半径や境界線などの装飾のない長方形に置き換えます。
  • void (*wait_for_finish)()すべてのバックグラウンド操作が終了するまで待ちます。(GPU操作など)
  • void * user_data 任意の目的のためのカスタムユーザーデータ

(簡単にするために、コールバックのパラメーターはここには示されていません。)


すべてのdraw_*コールバックは、最初のパラメーターとして現在へのポインターdraw_ctxを受け取ります。

他のパラメータの中には、何を描画するかを指示する記述子があります。たとえば、 draw_rectlv_draw_rect_dsc_t から呼ばれて、lv_draw_linelv_draw_line_dsc_t から呼ばれます。

draw_dsc に従って正しくレンダリングするには、LVGLの枠型モデルとフィールドの意味に精通している必要があります。

フィールドの名前と意味は、Styleプロパティの名前と同じ意味です。

戻る : Previous

Initialization

英文 自動翻訳

The lv_disp_drv_t has 4 fields related to the draw context:

  • lv_draw_ctx_t * draw_ctx Pointer to the draw_ctx of this display
  • void (*draw_ctx_init)(struct _lv_disp_drv_t * disp_drv, lv_draw_ctx_t * draw_ctx) Callback to initialize a draw_ctx
  • void (*draw_ctx_deinit)(struct _lv_disp_drv_t * disp_drv, lv_draw_ctx_t * draw_ctx) Callback to de-initialize a draw_ctx
  • size_t draw_ctx_size Size of the draw context structure. E.g. sizeof(lv_draw_sw_ctx_t)

When you ignore these fields, LVGL will set default values for callbacks and size in lv_disp_drv_init() based on the configuration in lv_conf.h.


lv_disp_drv_register() will allocate a draw_ctx based on draw_ctx_size and call draw_ctx_init() on it.

However, you can overwrite the callbacks and the size values before calling lv_disp_drv_register().

It makes it possible to use your own draw_ctx with your own callbacks.

lv_disp_drv_t には、描画コンテキストに関連する4つのフィールドがあります。
  • lv_draw_ctx_t * draw_ctx : このディスプレイの draw_ctx へのポインタ
  • void (*draw_ctx_init)(struct _lv_disp_drv_t * disp_drv, lv_draw_ctx_t * draw_ctx) : draw_ctx を初期化するためのコールバック
  • void (*draw_ctx_deinit)(struct _lv_disp_drv_t * disp_drv, lv_draw_ctx_t * draw_ctx) : draw_ctxの初期化を解除するためのコールバック
  • size_t draw_ctx_size : 描画コンテキスト構造のサイズ。例えばsizeof(lv_draw_sw_ctx_t)

これらのフィールドを無視した場合、LVGLは lv_conf.h の configuration に基づき lv_disp_drv_init() にコールバックとサイズのデフォルト値を設定します。


lv_disp_drv_register()draw_ctx_size に基づいて draw_ctx を割り当て、その上で draw_ctx_init() を呼び出します。

ただし、を呼び出す前に、コールバックとサイズの値を上書きできますlv_disp_drv_register()

それはあなた自身のコールバックで、あなた自身である draw_ctx を使うことを可能にします。

戻る : Previous

Software renderer

英文 自動翻訳

LVGL's built in software renderer extends the basic lv_draw_ctx_t structure and sets the draw callbacks. It looks like this:

 typedef struct {
    /** Include the basic draw_ctx type*/
     lv_draw_ctx_t base_draw;
 
     /** Blend a color or image to an area*/
     void (*blend)(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend_dsc_t * dsc);
 } lv_draw_sw_ctx_t;

Set the draw callbacks in draw_ctx_init() like:

 draw_sw_ctx->base_draw.draw_rect = lv_draw_sw_rect;
 draw_sw_ctx->base_draw.draw_letter = lv_draw_sw_letter;
 ...


LVGLに組み込まれているソフトウェアレンダラーは、基本の構造体lv_draw_ctx_tを拡張し、描画コールバックを設定します。次のようになります。

 '''typedef struct {
    /**基本的なdraw_ctxタイプを含めます*/
     lv_draw_ctx_t base_draw;
 
     /**色または画像を領域にブレンドします*/
     void* blend)(lv_draw_ctx_t * draw_ctxconst lv_draw_sw_blend_dsc_t * dsc;
 } lv_draw_sw_ctx_t;'''

draw_ctx_init()の中では次のよう に描画コールバックを設定します。

 '''draw_sw_ctx-> base_draw.draw_rect = lv_draw_sw_rect;
 draw_sw_ctx-> base_draw.draw_letter = lv_draw_sw_letter;
 ...'''
戻る : Previous

Blend callback

英文 自動翻訳

As you saw above the software renderer adds the blend callback field. It's a special callback related to how the software renderer works. All draw operations end up in the blend callback which can either fill an area or copy an image to an area by considering an optional mask.

The lv_draw_sw_blend_dsc_t parameter describes what and how to blend. It has the following fields:

  • const lv_area_t * blend_area The area with absolute coordinates to draw on draw_ctx->buf. If src_buf is set, it's the coordinates of the image to blend.
  • const lv_color_t * src_buf Pointer to an image to blend. If set, color is ignored. If not set fill blend_area with color
  • lv_color_t color Fill color. Used only if src_buf == NULL
  • lv_opa_t * mask_buf NULL if ignored, or an alpha mask to apply on blend_area
  • lv_draw_mask_res_t mask_res The result of the previous mask operation. (LV_DRAW_MASK_RES_...)
  • const lv_area_t * mask_area The area of mask_buf with absolute coordinates
  • lv_opa_t opa The overall opacity
  • lv_blend_mode_t blend_mode E.g. LV_BLEND_MODE_ADDITIVE
上で見たように、ソフトウェアレンダラーはblendコールバックフィールドを追加します。これは、ソフトウェアレンダラーの動作に関連する特別なコールバックです。すべての描画操作はblendコールバックで終了します。コールバックは、オプションのマスクを考慮して、領域を塗りつぶすか、画像を領域にコピーすることができます。

この パラメータlv_draw_sw_blend_dsc_tは、何をどのようにブレンドするかを記述します。次のフィールドがあります。

  • const lv_area_t * blend_areadraw_ctx->bufを描画する絶対座標を持つ領域 。src_bufが設定されている場合、ブレンドする画像の座標です。
  • const lv_color_t * src_buf ブレンドする画像へのポインタ。設定されている場合、colorは無視されます。設定されていない場合、colorblend_areaを塗りつぶします。
  • lv_color_t color 塗りつぶしの色。src_buf == NULLの場合にのみ使用されます
  • lv_opa_t * mask_buf 無視された場合はNULL、またはblend_areaに適用するアルファマスク
  • lv_draw_mask_res_t mask_res 前のマスク操作の結果。( LV_DRAW_MASK_RES_...
  • const lv_area_t * mask_areamask_buf 絶対座標のある領域
  • lv_opa_t opa 全体的な不透明度
  • lv_blend_mode_t blend_mode 例えば LV_BLEND_MODE_ADDITIVE
戻る : Previous

Extend the software renderer

New blend callback

英文 自動翻訳

Let's take a practical example: you would like to use your MCUs GPU for color fill operations only.

As all draw callbacks call blend callback to fill an area in the end only the blend callback needs to be overwritten.

First extend lv_draw_sw_ctx_t:

 /*We don't add new fields, so just for clarity add new type*/
 typedef lv_draw_sw_ctx_t my_draw_ctx_t;
 
 void my_draw_ctx_init(lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx)
 {
     /*Initialize the parent type first */
     lv_draw_sw_init_ctx(drv, draw_ctx);
 
     /*Change some callbacks*/
     my_draw_ctx_t * my_draw_ctx = (my_draw_ctx_t *)draw_ctx;
 
     my_draw_ctx->blend = my_draw_blend;
     my_draw_ctx->base_draw.wait_for_finish = my_gpu_wait;
 }


After calling lv_disp_draw_init(&drv) you can assign the new draw_ctx_init callback and set draw_ctx_size to overwrite the defaults:

 static lv_disp_drv_t drv;
 lv_disp_draw_init(&drv);
 drv->hor_res = my_hor_res;
 drv->ver_res = my_ver_res;
 drv->flush_cb = my_flush_cb;
 
 /*New draw ctx settings*/
 drv->draw_ctx_init = my_draw_ctx_init;
 drv->draw_ctx_size = sizeof(my_draw_ctx_t);
 
 lv_disp_drv_register(&drv);


This way when LVGL calls blend it will call my_draw_blend and we can do custom GPU operations.

Here is a complete example:

 void my_draw_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend_dsc_t * dsc)
 {
     /*Let's get the blend area which is the intersection of the area to fill and the clip area.*/
     lv_area_t blend_area;
     if(!_lv_area_intersect(&blend_area, dsc->blend_area, draw_ctx->clip_area)) return;  /*Fully clipped, nothing to do*/
 
     /*Fill only non masked, fully opaque, normal blended and not too small areas*/
     if(dsc->src_buf == NULL && dsc->mask == NULL && dsc->opa >= LV_OPA_MAX &&
        dsc->blend_mode == LV_BLEND_MODE_NORMAL && lv_area_get_size(&blend_area) > 100) {
 
         /*Got the first pixel on the buffer*/
         lv_coord_t dest_stride = lv_area_get_width(draw_ctx->buf_area); /*Width of the destination buffer*/
         lv_color_t * dest_buf = draw_ctx->buf;
         dest_buf += dest_stride * (blend_area.y1 - draw_ctx->buf_area->y1) + (blend_area.x1 - draw_ctx->buf_area->x1);
 
         /*Make the blend area relative to the buffer*/      
         lv_area_move(&blend_area, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1);
         
         /*Call your custom gou fill function to fill blend_area, on dest_buf with dsc->color*/  
         my_gpu_fill(dest_buf, dest_stride, &blend_area, dsc->color);
     } 
     /*Fallback: the GPU doesn't support these settings. Call the SW renderer.*/
     else {
       lv_draw_sw_blend_basic(draw_ctx, dsc);
     }
 }


The implementation of wait callback is much simpler:

 void my_gpu_wait(lv_draw_ctx_t * draw_ctx)
 {
     while(my_gpu_is_working());
     
     /*Call SW renderer's wait callback too*/
     lv_draw_sw_wait_for_finish(draw_ctx);
 }

実際の例を見てみましょう。MCUGPUをカラーフィル操作にのみ使用したいとします。


すべての描画コールバックはコールバックblendを呼び出して最終的に領域を埋めるため、blendコールバックのみを上書きする必要があります。

最初の拡張lv_draw_sw_ctx_t

 / *新しいフィールドは追加しないため、わかりやすくするために新しいタイプを追加します* /
 typedef lv_draw_sw_ctx_t my_draw_ctx_t;
 
 void my_draw_ctx_initlv_disp_drv_t * drvlv_draw_ctx_t * draw_ctx
 {
     /*最初に親タイプを初期化します*/
     lv_draw_sw_init_ctxdrvdraw_ctx;
 
     /*一部のコールバックを変更します*/
     my_draw_ctx_t * my_draw_ctx =my_draw_ctx_t *draw_ctx;
 
     my_draw_ctx-> blend = my_draw_blend;
     my_draw_ctx-> base_draw.wait_for_finish = my_gpu_wait;
 }

lv_disp_draw_init(&drv)を呼び出した後、新しいコールバックdraw_ctx_initdraw_ctx_sizeを割り当て、デフォルトを上書きするように 設定できます。

 static lv_disp_drv_t drv;
 lv_disp_draw_init(&drv;
 drv-> hor_res = my_hor_res;
 drv-> ver_res = my_ver_res;
 drv-> flush_cb = my_flush_cb;
 
 /*新しい描画ctx設定*/
 drv-> draw_ctx_init = my_draw_ctx_init;
 drv-> draw_ctx_size = sizeofmy_draw_ctx_t;
 
 lv_disp_drv_register(&drv;


このようにして、LVGLがblend呼び出すと、my_draw_blendが呼び出され、カスタムGPU操作を実行できます。

完全な例を次に示します。

 void my_draw_blendlv_draw_ctx_t * draw_ctxconst lv_draw_sw_blend_dsc_t * dsc
 {
     /*塗りつぶす領域とクリップ領域の交点であるブレンド領域を取得しましょう。*/
     lv_area_t blend_area;
     if(!_ lv_area_intersect(&blend_areadsc-> blend_areadraw_ctx-> clip_area))return; / *完全にクリップされ、何もしません* /
 
     / *マスクされていない、完全に不透明な、通常のブレンドで、小さすぎない領域のみを塗りつぶします* /
     ifdsc-> src_buf == NULL && dsc-> mask == NULL && dsc-> opa> = LV_OPA_MAX &&
        dsc-> blend_mode == LV_BLEND_MODE_NORMAL && lv_area_get_size(&blend_area> 100{
 
         /*バッファの最初のピクセルを取得しました*/
         lv_coord_t dest_stride = lv_area_get_widthdraw_ctx-> buf_area; /*宛先バッファの幅*/
         lv_color_t * dest_buf = draw_ctx-> buf;
         dest_buf + = dest_stride *blend_area.y1-draw_ctx-> buf_area-> y1+blend_area.x1-draw_ctx-> buf_area-> x1;
 
         /*バッファを基準にしてブレンド領域を作成します*/      
         lv_area_move(&blend_area-draw_ctx-> buf_area-> x1-draw_ctx-> buf_area-> y1;
         
         /*カスタムgoufill関数を呼び出して、dest_bufのblend_areaをdsc->colorで塗りつぶします*/  
         my_gpu_filldest_bufdest_stride、&blend_areadsc-> color;
     } 
     / *フォールバック:GPUはこれらの設定をサポートしていませんSWレンダラーを呼び出します。*/
     そうしないと {
       lv_draw_sw_blend_basicdraw_ctxdsc;
     }
 }


待機コールバックの実装ははるかに簡単です。

 void my_gpu_waitlv_draw_ctx_t * draw_ctx
 {
     whilemy_gpu_is_working());
     
     /*SWレンダラーの待機コールバックも呼び出します*/
     lv_draw_sw_wait_for_finishdraw_ctx;
 }
戻る : Previous

New rectangle drawer

英文 自動翻訳

If your MCU has a more powerful GPU that can draw e.g. rounded rectangles you can replace the original software drawer too. A custom draw_rect callback might look like this:

 void my_draw_rect(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dsc, const lv_area_t * coords)
 {
   if(lv_draw_mask_is_any(coords) == false && dsc->grad == NULL && dsc->bg_img_src == NULL &&
      dsc->shadow_width == 0 && dsc->blend_mode = LV_BLEND_MODE_NORMAL) 
   {
     /*Draw the background*/
     my_bg_drawer(draw_ctx, coords, dsc->bg_color, dsc->radius);
     
     /*Draw the border if any*/
     if(dsc->border_width) {
       my_border_drawer(draw_ctx, coords, dsc->border_width, dsc->border_color, dsc->border_opa)
     }
     
     /*Draw the outline if any*/
     if(dsc->outline_width) {
       my_outline_drawer(draw_ctx, coords, dsc->outline_width, dsc->outline_color, dsc->outline_opa, dsc->outline_pad)
     }
   } 
   /*Fallback*/
   else {
     lv_draw_sw_rect(draw_ctx, dsc, coords);
   }
 }

my_draw_rect can fully bypass the use of blend callback if needed.

MCUに丸みを帯びた長方形などを描画できるより強力なGPUがある場合は、元のソフトウェアドロワーを置き換えることもできます。カスタムdraw_rectコールバックは次のようになります。
 void my_draw_rectlv_draw_ctx_t * draw_ctxconst lv_draw_rect_dsc_t * dscconst lv_area_t * coords
 {
   iflv_draw_mask_is_anycoords== false && dsc-> grad == NULL && dsc-> bg_img_src == NULL &&
      dsc-> shadow_width == 0 && dsc-> blend_mode = LV_BLEND_MODE_NORMAL
   {
     /*背景を描く*/
     my_bg_drawerdraw_ctxcoordsdsc-> bg_c​​olordsc-> radius;
     
     /*境界線がある場合は描画します*/
     ifdsc-> border_width{
       my_border_drawerdraw_ctxcoordsdsc-> border_widthdsc-> border_colordsc-> border_opa
     }
     
     /*もしあれば輪郭を描きます*/
     ifdsc-> overlay_width{
       my_outline_drawerdraw_ctxcoordsdsc->outline_widthdsc->outline_colordsc->outline_opadsc->outline_pad
     }
   } 
   /*後退する*/
   そうしないと {
     lv_draw_sw_rectdraw_ctxdsccoords;
   }
 }

必要に応じて、my_draw_rectblendblend コールバック の使用を完全にバイパスできます。

戻る : Previous

Fully custom draw engine

英文 自動翻訳

For example if your MCU/MPU supports a powerful vector graphics engine you might use only that instead of LVGL's SW renderer.


In this case, you need to base the renderer on the basic lv_draw_ctx_t (instead of lv_draw_sw_ctx_t) and extend/initialize it as you wish.

たとえば、MCU / MCUが強力なベクターグラフィックエンジンをサポートしている場合は、LVGLのSWレンダラーの代わりにそれだけを使用できます。


この場合、基本に基づいて、(lv_draw_sw_ctx_tではなく)lv_draw_ctx_tレンダラーを必要に応じて拡張/初期化する必要があります。

戻る : Previous