⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 framebuf-iterating.html

📁 ecos3.0 beta 的官方文档,html格式
💻 HTML
📖 第 1 页 / 共 2 页
字号:
>.
More specifically, <CODE
CLASS="PARAMETER"
>dx</CODE
> should move the current
horizontal position one pixel to the right of the right-most pixel
modified, such that
<TT
CLASS="LITERAL"
>(x&nbsp;+&nbsp;dx)&nbsp;-&nbsp;x0</TT
> gives the width
of the bounding box. Similarly <CODE
CLASS="PARAMETER"
>dy</CODE
> should move
the current vertical position one pixel below the bottom-most pixel
modified. In typical code the current pixel position will already
correspond in part or in whole to the bounding box corner, as a
consequence of iterating over the block of memory.
    </P
><P
>If a pixel variable has been used only for reading framebuffer memory,
not for modifying it, then it should still be flushed. A
<TT
CLASS="LITERAL"
>FLUSHABS</TT
> with a width and height of 0 can be used
to indicate that the bounding box is empty. If it is known that the
framebuffer device being used does not support double-buffering then
again it is possible to specify an empty bounding box. Otherwise
portable code should specify a correct bounding box. If the
framebuffer device that ends up being used does not support double
buffering then the relevant macro arguments are eliminated at
compile-time and do not result in any unnecessary code. In addition if
there is no cached value or other state then the whole flush operation
will be a no-op and no code will be generated.
    </P
><P
>Failure to perform the flush may result in strange drawing artefacts
on some displays which can be very hard to debug. A
<CODE
CLASS="FUNCTION"
>FLUSHABS</CODE
> or <CODE
CLASS="FUNCTION"
>FLUSHREL</CODE
> macro
only needs to be invoked once, at the end of the iteration.
    </P
><P
>The <TT
CLASS="LITERAL"
>SET</TT
> macro sets the current position within the
framebuffer. It can be used many times within an iteration. However
it tends to be somewhat more expensive than <TT
CLASS="LITERAL"
>ADDX</TT
> or
<TT
CLASS="LITERAL"
>ADDY</TT
>, so usually <TT
CLASS="LITERAL"
>SET</TT
> is only
executed once at the start of an iteration.
    </P
><TABLE
BORDER="5"
BGCOLOR="#E0E0F0"
WIDTH="70%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>    CYG_FB_PIXEL0_VAR(FRAMEBUF);
    CYG_FB_PIXEL0_SET(FRAMEBUF, x, y);
    &#8230;
    CYG_FB_PIXEL0_FLUSHREL(FRAMEBUF, x, y, 0, 0);</PRE
></TD
></TR
></TABLE
><P
>The <TT
CLASS="LITERAL"
>GET</TT
> macro retrieves the x and y coordinates
corresponding to the current position. It is provided mainly for
symmetry, but can prove useful for debugging.
    </P
><TABLE
BORDER="5"
BGCOLOR="#E0E0F0"
WIDTH="70%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>    CYG_FB_PIXEL0_VAR(FRAMEBUF);
    CYG_FB_PIXEL0_SET(FRAMEBUF, x, y);
    &#8230;
#ifdef DEBUG
    CYG_FB_PIXEL0_GET(FRAMEBUF, new_x, new_y);
    diag_printf("Halfway through: x now %d, y now %d\n", new_x, new_y);
#endif
    &#8230;
    CYG_FB_PIXEL0_FLUSHREL(FRAMEBUF, x, y, 0, 0);</PRE
></TD
></TR
></TABLE
><P
>The <TT
CLASS="LITERAL"
>ADDX</TT
> and <TT
CLASS="LITERAL"
>ADDY</TT
> macros adjust
the current position. The most common increments are 1 and -1, moving
to the next or previous pixel horizontally or vertically, but any
increment can be used.
    </P
><TABLE
BORDER="5"
BGCOLOR="#E0E0F0"
WIDTH="70%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>    CYG_FB_PIXEL0_VAR(FRAMEBUF);
    CYG_FB_PIXEL0_SET(FRAMEBUF, x, y);
    for (rows = height; rows; rows--) {
        for (columns = width; columns; columns--) {
            &lt;perform operation&gt;
            CYG_FB_PIXEL0_ADDX(FRAMEBUF, 1);
        }
        CYG_FB_PIXEL0_ADDX(FRAMEBUF, -1 * width);
        CYG_FB_PIXEL0_ADDY(FRAMEBUF, 1);
    }
    CYG_FB_PIXEL0_FLUSHREL(FRAMEBUF, x, y, width, 0);</PRE
></TD
></TR
></TABLE
><P
>Here the current position is moved one pixel to the right each time
around the inner loop. In the outer loop the position is first moved
back to the start of the current row, then moved one pixel down.
For the final flush the current x position is off by
<TT
CLASS="LITERAL"
>width</TT
>, but the current y position is already correct.
    </P
><P
>The final two macros <TT
CLASS="LITERAL"
>READ</TT
> and
<TT
CLASS="LITERAL"
>WRITE</TT
> can be used to examine or update the current
pixel value.
    </P
><TABLE
BORDER="5"
BGCOLOR="#E0E0F0"
WIDTH="70%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>    CYG_FB_PIXEL0_VAR(FRAMEBUF);
    CYG_FB_PIXEL0_SET(FRAMEBUF, x, y);
    for (rows = height; rows; rows--) {
        for (columns = width; columns; columns--) {
            cyg_fb_colour colour = CYG_FB_PIXEL0_READ(FRAMEBUF);
            if (colour == colour_to_replace) {
                CYG_FB_PIXEL0_WRITE(FRAMEBUF, replacement);
            }
            CYG_FB_PIXEL0_ADDX(FRAMEBUF, 1);
        }
        CYG_FB_PIXEL0_ADDX(FRAMEBUF, -1 * width);
        CYG_FB_PIXEL0_ADDY(FRAMEBUF, 1);
    }
    CYG_FB_PIXEL0_FLUSHREL(FRAMEBUF, x, y, width, 0);</PRE
></TD
></TR
></TABLE
></DIV
><DIV
CLASS="REFSECT1"
><A
NAME="FRAMEBUF-ITERATION-OTHER"
></A
><H2
>Concurrent Iterations</H2
><P
>Although uncommon, in some cases application code may need to iterate
over two or more blocks. An example might be an advanced block move
where each copied pixel requires some processing. To support this
there are <TT
CLASS="LITERAL"
>PIXEL1</TT
>, <TT
CLASS="LITERAL"
>PIXEL2</TT
> and
<TT
CLASS="LITERAL"
>PIXEL3</TT
> variants of all the
<TT
CLASS="LITERAL"
>PIXEL0</TT
> macros. For example:
    </P
><TABLE
BORDER="5"
BGCOLOR="#E0E0F0"
WIDTH="70%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>    CYG_FB_PIXEL0_VAR(FRAMEBUF);
    CYG_FB_PIXEL1_VAR(FRAMEBUF);

    CYG_FB_PIXEL0_SET(FRAMEBUF, dest_x, dest_y_);
    CYG_FB_PIXEL1_SET(FRAMEBUF, source_x, source_y);
    for (rows = height; rows; rows--) {
        for (columns = width; columns; columns--) {
            colour = CYG_FB_PIXEL1_READ(FRAMEBUF);
            &lt;do some processing on colour&gt;
            CYG_FB_PIXEL0_WRITE(FRAMEBUF, colour);
            CYG_FB_PIXEL0_ADDX(FRAMEBUF, 1);
            CYG_FB_PIXEL1_ADDX(FRAMEBUF, 1);
        }
        CYG_FB_PIXEL0_ADDX(FRAMEBUF, -100);
        CYG_FB_PIXEL0_ADDY(FRAMEBUF, 1);
        CYG_FB_PIXEL1_ADDX(FRAMEBUF, -100);
        CYG_FB_PIXEL1_ADDY(FRAMEBUF, 1);
    }

    CYG_FB_PIXEL0_FLUSHABS(FRAMEBUF, source_x, source_y, width, height);
    CYG_FB_PIXEL1_FLUSHABS(FRAMEBUF, 0, 0, 0, 0);  // Only used for reading</PRE
></TD
></TR
></TABLE
><P
>The <TT
CLASS="LITERAL"
>PIXEL0</TT
>, <TT
CLASS="LITERAL"
>PIXEL1</TT
>,
<TT
CLASS="LITERAL"
>PIXEL2</TT
> and <TT
CLASS="LITERAL"
>PIXEL3</TT
> macros all use
different local variables so there are no conflicts. The variable
names also depend on the framebuffer device. If the target has two
displays and two active framebuffer devices then the pixel macros can
be used with the two devices without conflict:
    </P
><TABLE
BORDER="5"
BGCOLOR="#E0E0F0"
WIDTH="70%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>    CYG_FB_PIXEL0_VAR(FRAMEBUF0);
    CYG_FB_PIXEL0_VAR(FRAMEBUF1);
    &#8230;</PRE
></TD
></TR
></TABLE
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="framebuf-drawing.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="ecos-ref.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="framebuf-porting.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Framebuffer Drawing Primitives</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="io-framebuf.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Writing a Framebuffer Device Driver</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -