`
wsliujian
  • 浏览: 96604 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

简要评说Adobe的FlashPlayer的渲染算法

阅读更多
前些时候看到CSDN上一篇文章介绍FlashPlayer的渲染效能是HTML 5的数倍文章,回想起几年来对Adobe的FlashPlayer研究,想从理论上探究一下为什么会有这样的结果,同时也解释一下针对传统硬件加速(非GPU方案)为什么Adobe的FlashPlayer会被批评的原因;
早些年在一家IC设计公司为一个低端平台(具有硬件3D加速)作官方的FlashPlayer的硬件加速,几个月下来,硬件渲染引擎做好了,但最后的结果非常出人意料 ----- 改用硬件加速后的效能居然比软件渲染的要差;为了解释其中的原因,我们还是先从Adobe的FlashPlayer软件渲染算法原理上入手;
事实上,FlashPlayer的2D渲染引擎使用的是最为常见的扫描线算法(Scanline算法),及简单的讲,是以虚拟显示设备(对于考虑抗锯齿的情况下,虚拟显示设备大于实际显示设备,如4 x 4抗锯齿,虚拟显示设备的纵向是实际显示设备的4倍)每条扫描线计算和矢量图形的各边(Edge)的交点,并根据不同的填充法则填充两个交点间的水平线;这样随着扫描线自上而下逐条计算完成后,在虚拟显示设备中即完成了一幅完整图形的构成,然后,再根据超采样算法,将虚拟显示设备上的图形输出到实际显示设备上,这样,在实际显示设备上即得到一幅完美的无锯齿的图形;以一定的速率重复以上动作,及可以得到连续的动画;FlashPlayer通过解析流式的swf文件,并按照指定的速度更新画面完成动画的播放,因此,我们已经有些简单的结论:
l  矢量运算是一个工程浩大的计算;这也解释了为什么FlashPlayer在多数平台上存在的效能问题;非常遗憾的是,当前实时2D矢量图形播放软件似乎只有FlashPlayer,所以这个黑锅是没办法了;
l  为什么高画质的显示效能要较低画质的差很多呢;因为在高画质下,FlashPlayer是使用的4 x 4的超采样抗锯齿,及表示通过扫描线计算交点的计算量是低画质的4倍;
(关于2D矢量图形显示,参考我之前的资源:http://download.csdn.net/source/5773340)
在实际的2D矢量引擎中,问题往往更为复杂,在考虑Cap和Join后,实际即使是一根很简单的折线或Bezier曲线都是由很多的曲线构成的(如图折线的两个端点 ---- Cap):

这样可以理解为什么现在为止鲜有可以和Adobe FlashPlayer相抗衡的实时2D矢量显示程序了,这是不是有些矛盾:为什么Adobe的FlashPlayer会一枝独秀呢?以上只是关于2D矢量图形显示的原理性解释,其他2D矢量显示引擎,如OpenVG(gingkoVG)、agg等使用的是完全相同的原理,Adobe的FlashPlayer相对通用的2D矢量显示引擎一定有他自己特殊的定义,仔细阅读Adobe关于FlashPlayer的官方技术文件(swf_file_format_spec_v10),我们很快发现了两处很有意思的说明:
l  FlashPlayer仅支持2阶的贝塞尔曲线(Quadratic Bezier),而不支持类似PostScript和OpenVG等传统2D矢量引擎中使用的3阶贝塞尔曲线(Cubic Bezier);


相对2阶Beizer曲线,3阶贝塞尔曲线单独一条在计算交点是增加的计算量似乎并不大:多了几次乘法运算;但在多数CPU体系中乘除法运算所消耗的时间会大于加减法,尤其在非常大的运算量下,其累积的差别就更大了;
l  在Adobe的官方文件中明确注明FlashPlayer不支持点划线(Dash)


为什么不支持Dash呢?事实上在矢量图形显示中,除了曲线和扫描线交点的计算外,最困难的是计算曲线的长度,Dash的显示必须依赖事先的曲线长度的计算;在实现gingkoVG时,不包含Dash功能的曲线显示其显示效能是使用Dash的4倍;
l  仅此而已吗?并不是,不过即使以上的约束,其显示效能已经“被提升”了数倍。在Adobe的FlashPlayer中,针对渲染同时使用了其他的一些优化算法,当然这些优化算法作为通用优化技术在多数2D矢量引擎中也会被使用;(参考:http://download.csdn.net/source/1998019)
非常遗憾的是多数2D矢量引擎因为需要考虑通用性,都会支持3阶贝塞尔曲线和点划线,甚至是圆弧(OpenVG),这样从算法层面上我们不难理解为什么那些使用标准2D渲染引擎(如gnash使用了agg)的开源FlashPlayer无法和Adobe的FlashPlayer的执行效能相比较了----- 因为FlashPlayer的2D渲染引擎是针对Flash播放的实时性的需要量身定做的;当然,Adobe的FlashPlayer除了这些外,在程序的优化上有很多高明之处,这些不是我们这里需要讨论的;
事情似乎就此可以告一段落了,但随着对FlashPlayer的深入研究,我们发现了一些更深入的问题 ----- 及Adobe的FlashPlayer被广为批评的硬件加速效能差的原因;在不考虑针对特殊GPU的硬件加速,我们仅仅考虑标准硬件加速方式(OpenGL ES/OpenVG)来解释这个问题;Adobe的FlashPlayer在诞生时,那个时候还没有通用的2D矢量显示标准(如OpenVG),其针对软件渲染的2D矢量图形显示可谓是亮点,在经过十几年的发展和优化,Adobe的2D软件矢量渲染引擎可谓是已经发展到尽善尽美了,这也可以解释为什么自FlashPlayer 4到FlashPlayer 8其渲染引擎一直没有太大的变化,也可以解释为什么Adobe FlashPlayer软件渲染的效能甚至会好于使用低端硬件加速的效能了;但,成也萧何败也萧何,过于完美的标准和算法阻碍了使用标准硬件加速的可能(针对特殊GPU的硬件加速,因为其灵活性不在我们的考虑中),我们继续仔细研究Adobe的官方文件,我们注意到,关于填充法则FlashPlayer相对传统的2D矢量引擎有不同之处:传统的2D矢量引擎(如OpenVG/gingkoVG)有两种填充法则:奇偶填充法则(Even-odd fill rule)和非零填充法则(Non-zero fill rule),而Adobe的FlashPlayer又增加了边边填充法则(Edge-edge fill rule),及多数2D矢量引擎针对每个Shape/Object使用单一的着色方式(RColor),而在边边填充法则中,一条边根据左右不同可以分别拥有两种不同的着色方式(color1/color2),当然Adobe这样做的原因是增加了软件渲染的灵活性,如在两个Shape相交时对于相交部分允许使用不同的着色方式,如图:


遗憾的是这样在使用标准图形加速引擎时(OpenVG/OpenGL)会为我们带来困惑:即针对一个Shape我们可能会有不同的着色方式,这似乎是有悖于多数2D矢量引擎;尽管针对边边填充法则我们可以视作是两个不同奇偶填充法则,但考虑到针对每条边因此可能随时变化的填充法则,具有单一Color的Shape的重新确认并非那么容易,尤其对于由曲线构成的Shape。不过这个问题相对2D矢量图形渲染并不是很麻烦,但我们因此可以发现针对现在多数传统2D矢量引擎,Adobe FlashPlayer似乎并不“友善” ----- 程序员必须小心编写一个中间层解决这些问题,这并非是Adobe的错误:在FlashPlayer诞生时这些2D矢量显示标准(OpenVG)还没有出现; 只是非常可惜的是Adobe的FlashPlayer并非开源程序(Adobe FlashPlayer的AVM2已经开源),因此,我们必须耐心等待Adobe为我们去作这些,除非我们不准备使用官方的FlashPlayer;
(我们自己使用OpenVG的FlashPlayer)

分享到:
评论

相关推荐

    install_flashplayer11x32_mssa_aih

    标题“install_flashplayer11x32_mssa_aih”指的是Adobe Flash Player 11的32位安装程序,这是一个用于在网页浏览器上播放Flash内容的软件。Flash Player是Adobe公司开发的一款广泛使用的多媒体应用程序,它支持动画...

    flash_player_npapi_linux.x86_64.tar.gz

    这将创建一个名为`flashplayer`的新目录,包含所有解压后的文件。 2. **查看解压后的文件**:解压后,你会看到以下四个文件: - `usr`: 这是一个模拟Linux系统的目录结构,包含了一些库和文件。 - `LGPL`: 表明...

    常见的算法类型及其简要介绍以及一个经典算法题的解析与代码示例

    常见的算法类型及其简要介绍以及一个经典算法题的解析与代码示例

    Apriori算法简要实现

    Apriori算法简要实现

    adobe flash cs4教程

    Adobe Flash CS4是一款由Adobe公司推出的交互式矢量图和Web动画设计工具,它在Web开发领域占有重要的地位,尤其在创建动态网页内容和在线多媒体交互方面。本教程聚焦于Flash CS4的基础操作和动画制作,但不涉及...

    分治算法的简要介绍

    简要介绍了分治算法的实现和应用场景,原理和相关的背景

    本文简要介绍了银行家算法

    银行家算法是一种避免死锁的著名算法,由艾兹格·迪杰斯特拉提出。它通过模拟资源分配的过程来预防死锁的发生,主要应用于多进程操作系统中。银行家算法的工作原理是预先检查系统分配资源给一个进程后是否能够满足...

    CFS调度算法简要介绍,简要介绍了CFS算法。

    ### CFS调度算法详解 #### 一、CFS算法概述 CFS (Completely Fair Scheduler) 调度算法是一种用于Linux内核的进程调度机制,旨在提供对进程的完全公平调度。它确保了所有进程根据其权重得到相对公平的CPU时间分配...

    本文简要介绍了贪心算法

    贪心算法是一种在每一步决策中都选取当前看来最好的选择,以期达到全局最优解的算法策略。这种算法不考虑后续步骤,只在当前步骤中做出最优选择。贪心算法的核心思想可以归纳为:在局部做出最优选择,以期望这些局部...

    本文简要介绍了遗传算法

    遗传算法是一种受自然选择和遗传学理论启发的搜索和优化算法,它属于进化算法的范畴。遗传算法在解决复杂优化问题方面表现出色,尤其在传统优化方法难以适用的情况下。这种算法模拟了生物进化的过程,通过迭代的方式...

    算法谜题(算法谜题).pdf

    - **前言**:简要介绍了本书的创作背景、目标受众以及如何使用本书。 - **致谢**:感谢了在本书编写过程中提供帮助的人士。 - **谜题列表**:列出了书中包含的所有谜题,分为三个难度级别:入门级、中级和高级。 - *...

    遗传算法综述(本文主要回顾了遗传算法的起源和发展历程, 并对遗传算法的基本原理及特点作了简要阐述。)

    ### 遗传算法综述 #### 一、遗传算法的起源与发展 遗传算法(Genetic Algorithm, GA)源于进化论和群体遗传学,是一种基于自然选择和遗传学原理的优化搜索技术。它通过模拟生物进化的过程来寻找问题的最优解。1960...

    Java实现遍历、排序、查找算法及简要说明.docx

    在本文档中,我们主要探讨了Java中关于遍历、排序和查找算法的实现和简要说明。首先,我们详细介绍了二叉树的遍历算法,包括四种主要的遍历方式:先序遍历、中序遍历、后序遍历和层次遍历。 1. **遍历算法**: - *...

    数据结构与算法简要教程.pdf

    本简要教程涵盖了这两个核心概念。 首先,算法是解决问题的步骤集合,它必须是可行的、确定的(每步都有唯一结果)、有限的(在有限步骤内结束)并且具备足够的信息以执行。算法的基本运算包括算术、逻辑、关系操作...

    MOG2, KNN, GMG 三种背景减除算法简要对比1

    在本文中,我们将探讨三种常见的背景减除算法:混合高斯模型(MOG2)、K近邻(KNN)以及通用混合模型(GMG),并进行简要对比。 **混合高斯模型(MOG2)** MOG2是一种基于高斯混合模型的背景减除算法,它通过学习...

    suanfachengxu_粒子群算法;回溯搜索算法;人工蜂群算法_算法程序源码_算法对比_

    本文将详细介绍标题中提到的三种优化算法:粒子群算法(PSO)、回溯搜索算法(BSA)以及人工蜂群算法(ACO),并简要探讨它们的程序源码实现以及如何进行算法对比。 1. **粒子群算法(PSO)**: - 粒子群算法是一...

    k-means算法简要

    k-means算法是一种广泛应用的无监督学习方法,主要用于数据聚类。它的主要任务是将给定的数据集划分为k个不同的簇(或类别),每个簇内的数据点尽可能相似,而不同簇之间的数据点则尽可能差异大。算法的核心在于迭代...

    现代优化算法简介与MATLAB实现

    本文主要介绍模拟退火算法,并简要概述遗传算法、蚁群算法和禁忌搜索算法。 #### 模拟退火算法 **1.1 算法简介** 模拟退火算法源于对固体物理中退火过程的模拟,旨在通过一种类似于金属冷却过程的方法来寻找优化...

Global site tag (gtag.js) - Google Analytics