·ChinaUnix首页 ·论坛 ·博客 
Linux首页 | Linux新闻 | Linux论坛 | Linux文档 | Linux下载 | Linux博客 | Linux搜索 | 开源项目孵化平台 | 《开源时代》
新手入门 | 安装启动 | 管理员指南 | 开发手册 | 桌面应用 | 程序开发 | 数据库 | 网络技术| CentOS | Fedora | MySQL | Apache | Ubuntu | Gentoo| OSCON08
  Linux时代 >> 技术文档 >> 桌面应用
 
[转]android graphics
来源: ChinaUnix博客  日期: 2009.01.04 17:39 (共有条评论) 我要评论
 

                android graphics
                > Hi All,
> I've been using SurfaceView and Surface for one of my graphics
> project.
> The problem keep bothering me is that the content in Surface's two
> graphic buffers does not synchronized so that when the "lockCanvas-
> drawCanvas-unlockCanvas" cycle is running, it shows different content
> and generate screen flicker.

Here is some information on how the Android graphics system works:
In Android, every window is implemented with an underlaying Surface
object. A Surface is an object that gets composited onto the
framebuffer by SurfaceFlinger, the sytem-wide screen composer.
Each Surface is double-buffered, it has a back buffer which is where
drawing takes place and a front buffer which is used for composition.

When "unlockCanvas()" is called, the back buffer is "posted", which
means it's being displayed and  becomes available again.

However, the *implementation* of this mechanism is done by swapping
the front and back buffers. The back buffer becomes the front buffer
and vice-versa.

This mechanism ensures that there is a minimal amount of buffer
copying (a post operation doesn't move any pixels around) and that
there is always a buffer for SurfaceFlinger to use for composition.
This last feature is very important because it ensures that the screen
never flickers and never shows any artifacts *and* that
SurfaceFlinger never has to wait for a Surface to be ready (its front
buffer is always ready by definition), this means that a badly written
application cannot slowdown or interfere with other application's
windows.

As a side note, it is worth noting that the main screen itself (the
frame buffer) is double-buffered as well and uses the same posting
mechanism than any regular surface.

It should appear now that because of this posting mechanism,
incremental updates are not supported; and this is /the/ key point.

Back to your question now:

> After doing a bit research, I got my conclusion (not sure if it is
> correct though) here:
> 1. There are two separate buffers of each Surface object. According to
> SDK, they were called "front buffer" and "back buffer".

> 2. Android's Surface does not behaves like regular "double-buffer"
> system, which means: draw everything in back buffer and then flip the
> back buffer into the front buffer.
> What Android Surface does seems to be: draw in buffer A and flip it on
> the screen, then in next cycle, draw buffer B and flip it on the
> screen. As the result, the content visible on the screen comes from
> buffer A, B, A, B, A, .... I'm using buffer "A" and "B" here instead
> of "front" and "back" because I think they have equal role in
> rendering cycle.

> 3. The Surface buffer's alternate work style causes problem when I'm
> doing partial update (repaint only a portion of the Surface) for the
> performance purpose. Because one "lockCanvas-drawCanvas-unlockCanvas"
> cycle only update one buffer, the other one remains untouched, then
> when next "lockCanvas-drawCanvas-unlockCanvas" comes, it shows you an
> old content on the screen so that the flicker happens.

You are correct in your analysis. Something that the documentation
doesn't emphasis clearly is that with such a mechanism, your *must*
draw every single pixel of the Surface's back buffer each-time. In
essence, the back buffer is not preserved in post. This is a common
behavior  of hardware-accelerated graphics systems.
There is fact an API on the underlaying Surface object that allows to
update only a portion of the back buffer (but even then, every pixel
of that portion need to be redrawn). It is implemented by copying back
the former back buffer (now in the front) to the new back buffer
(formerly in the front). Unfortunately, this API is not exposed to
SurfaceView at the moment. I'm hoping to have this feature added
eventually.

> 4. My work around (works but with tremendous performance penalty)
> When I'm doing partial Surface update, I do the following thing in
> each rendering cycle:

The best solution available right now to solve this problem, is to do
all of your rendering into your own bitmap and simply copy it into the
back buffer:
- create a bitmap
- attach a canvas to it
- do the rendering into that canvas
- lockCanvas
- draw your bitmap into the backbuffer
- unlockAndPost

Note that this method involves an extra copy of the whole buffer size,
but it is in fact not slower than what it would have been if the
posting mechanism worked as you expected/suggested.

> 5. In order to improve my solution a bit, I try to use
> "s.unlockCanvas(b);" instead of "s.unlockCanvasAndPost(b);" because I
> really do not need to make the second buffer flipping, I just need to
> synchronize its content. However, unlockCanvas() generates a "Illegal
> argument" exception. I can not figure out the reason.

I will investigate the error you are reporting. However, this solution
would not have worked because unlockCanvas() is essentially a no-op,
it doesn't post the back buffer, which means it won't make it visible.
It is only intended to be used in very special situations.
> I have noticed someone has met the similar SurfaceView problem, see
> the following topic:
http://groups.google.com/group/android-developers/browse_thread/threa
...
> I'm not sure if someone has any better solution than mine?
> Is there a way to notify Surface that I would like to use a fixed
> buffer as front buffer?

There is no way to do that at the moment, but we might add this
functionality eventually. Note that in that case, your Surface will
suffer from tearing, so it won't be suited for Surfaces that do a lot
of animations
               
               
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/85193/showart_1773412.html
  发表评论 查看评论(共有条评论)
 
 


最新资讯更多>> 
· 谷歌劝说诺基亚采用Android操作..
· Apache 基金会确认退出 JCP 执..
· Chrome 10 新功能探秘:新增GP..
· 金山宣布开源其安全软件
· 女黑客在开源会议上抱受骚扰
· 21款值得关注的Linux游戏
· 马化腾:腾讯半年后彻底转型,..
· [多图] Chrome OS 预发布版本多..
· Lubuntu 11.04 默认应用抢先一览
· Red Hat宣布收购云计算软件提供..
论坛热点更多>> 
· do_execve时候用户栈中参数的..
· swapinfo -atm 问题
· Linux 的优点简述
· VM虚拟机上得Red Hat Linux上..
· 我看成了上海男人喜欢女人毛..
· 校车展览,看了你就知道
· 在遇到他之前,唯一需要做的..
· GRUB的疑问
· 从来没有人真正付足书价——..
· 云存储 vs 网盘
文档更新更多>> 
· orcale queue
· 谁可以推荐几本经典的操作系统的..
· 【北京】某物联网公司招云计算应..
· 【北京】某物联网公司招云计算应..
· 谁能推荐几本关于操作系统的书
· 如何添加网络接口eth1
· 葡萄牙语入门教材的选取与经验分享
· 葡萄牙语就业前景分析
· 葡萄牙语学习经验交流
· Щ
 
关于我们 | 联系方式 | 广告合作 | 诚聘英才 | 网站地图 | 友情链接 | 免费注册

Copyright © 2001-2009 ChinaUnix.net All Rights Reserved

感谢所有关心和支持过ChinaUnix的朋友们

京ICP证:060528号