Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
RT-Thread一般讨论
[转帖]淺談 Google Skia 圖形處理引擎
发布于 2009-04-01 15:27:22 浏览:3450
订阅该版
[tocm] 淺談 Google Skia 圖形處理引擎 ---- from JServ [http://blog.linux.org.tw/~jserv/](http://blog.linux.org.tw/~jserv/) 2008 年九月,Google 宣佈以改良過的 WebKit 為核心的網路瀏覽器 Chrome,揭露了眾多新特徵,比方說嶄新的 [V8] JavaScript (ECMAscript) 執行引擎,或許因為太亮眼,掩蔽了所使用另一個開放原始碼專案 [skia],後者是個 2D 向量圖形處理函式庫,包含字型、座標轉換,以及點陣圖都有高效能且簡潔的表現。不僅用於 Google Chrome 瀏覽器,新興的 Android 開放手機平台也採用 skia 作為繪圖處理,搭配 OpenGL/ES 與特定的硬體特徵,強化顯示的效果,本文簡介 Google Skia 的歷史背景、應用層面,並探討其程式設計模型。 Google 為了搭建 Open Handset Alliance (OHA) 的 Android 平台,布局極久,背後的百人研發團隊部份來自之前的併購案,其中兩項具指標性意義: * 2005 年八月 17 日,收購美國 Android 公司,業務是手機軟體開發,這當然就是現在開放源碼 Android 計畫的前身 * 2005 年十一月,收購美國 Skia 公司,業務是向量繪圖軟體 被 Google 收購前的 Android 公司有著在 IT 產業為人所津津樂道的成果,本文就不多談,而 Skia 公司自然也不是省油的燈。Skia Inc. 設立於北卡羅萊納州的 Chapel HIll,由 Michael Reed (也稱為 Mike Reed) 所創辦,他在圖形技術領域是相當頂尖的人物,與 Benoit Schillings (BeOS 主要開發者, Be Inc. 第二位工程師,現為 Nokia CTO) 於專業手機軟體開發公司 OpenWave 共事時,即在該公司產品 OpenWave Phone Suite Version 7.0 (以下簡稱 V7) 引入精湛的向量圖形技術,在 50-300 kb 空間的實做中,提供了圖層 overlay 之間 alpha blended 預覽、全功能向量矩陣轉換等進階功能。在加入 OpenWave 之前,Mike Reed 服務於 Apple,代表專案為 QuickDraw GX,主導進階圖形與字型處理技術。Benoit Schillings 離開 OpenWave 轉任 Trolltech CTO 期間,Mike Reed 開創了 Skia Inc.,該公司第一個產品為 SGL (Skia Graphics Library),一個非常嚴謹的向量顯示引擎,能在低端設備比如手機、電視及其它手持設備之上,呈現高品質的 2D 圖形。根據 LocalTechWire 的描述: "Skia’s first product, SGL, is a portable graphics engine capable of rendering state-of-the-art 2D graphics on low-end devices such as mobile phones, TVs, and handhelds,” the Web site said. “SGL is feature-set compatible with existing 2D standards, making it ideal to serve as a back-end for public formats such as SVG, PDF, and OpenVG. SGL is licensed as source or binary, and can be customized to match specific HW/framebuffer requirements.” 自 2005 年 Skia 被 Google 收購後,一直相當神秘低調,直到 2007 年初,Skia GL 相關的程式碼才被揭露,作為 Google Android 平台的圖形引擎,稍候的 Google Chrome 瀏覽器也採用 Skia 引擎。隨著 Android 與 Chrome (開放版本稱為 "Chromium") 兩大專案公佈程式碼後,skia 也一併公開原始程式碼,以 Apache License v2 釋出 (注意,這意味著與 GPLv2 授權不相容),而 Android 與 Chrome 的程式碼庫中都有一份 [skia] 的複製,因需求不同,做了部份的修改,比方說 Chrome 專案底下的 [chrome/trunk/src/skia],需要注意的是,Skia 本身是不涉及底層環境,如 Linux Framebuffer 或 Gtk+ 銜接的處理,這也是何以 Android (透過 Linux Framebuffer) 與 Chrome (開發中的 Linux 版本使用 Gtk+) 需要提供一份修改,以便系統接軌,關於這方面的資訊,可參照 Google Chromium 的開發日誌 [Graphics in Google Chrome] 相較於 Firefox 1.x,後繼的 Firefox 2.x/3.x 在圖形顯示方面有相當大的進展,很大層面歸功於引入 Cario 向量圖形程式庫來處理網頁繪製,而 Skia 就相當於扮演 Cairo 的角色,不過更輕量些。快速發展的 WebKit 儼然是從桌面應用跨足移動裝置之網頁引擎解決方案的首選,Apple 與 Google 都有為數可觀的全職工程師投入,拜網際網路的威力,也有其他廠商與團體個人積極投入開發,目前 WebKit 支持的圖形函式庫計有 Cairo, Gtk+, Qt4, WxWidgets, Cg (Mac 的非開放原始碼函式庫), Skia 等等,並以 WebKit 中 class GraphicsContext 處理前述圖形函式庫的實做,可針對不同平台的特性,規範不同平台所需的巨集與成員,詳情可參考程式碼 WebCore/platform/graphics/GraphicsContext.{h,cpp}。 Skia 以 C++ 實做,程式碼約八萬行,基本某些未知的因素,可參考的文件相當有限,但 Chromium 的 SVN log 與程式碼則是現在最完整的文件,以下是其特徵: * 高度優化的軟體 rasteriser (module sgl/) * 選擇性透過 OpenGL/ES,加速特定操作,如 shader 與 textures (module gl/) * 動畫處理能力(module animator/) * 內建 SVG 支援 (module (svg/) * 內建若干 image codec,如 PNG, JPEG, GIF, BMP (modules images/) * 內建文字處理,但缺乏泰文、藏文一類複雜文字處理的能力 * 效能特性: o 對 image 與特定資料型態的 Copy-on-write o 內部記憶體管理,謹慎地被免 fragmentation o Thread-safety Skia 實做所需的相依性: * 字型: FreeType (值得注意的是,FreeType 的維護者 David Turner 目前任職於 Google), Windows GDI * 多執行緒模型: pthread, Windows threads * XML: expat, tinyxml 理解歷史背景,我們終於可以來作點有趣的事。首先,自 Google Code 取得 Skia 原始程式碼: # svn co [http://skia.googlecode.com/svn/trunk](http://skia.googlecode.com/svn/trunk) skia-trunk 乍看這「清爽」的目錄架構,很難想像過去這是商業軟體,或許 Google 有些「不能說的秘密」,除了 samplecode/ 目錄若干的程式碼之外,就幾乎沒有充分的文檔了。用 svn log 可瀏覽 Skia 開發的紀錄,"reed@android.com" 就是 Mike Reed 本人,至今仍相當活躍地改良 Skia 的實做。編譯方式很單純,先看看說明:(本文對應於 svn r130) # cd skia-trunk # make help 可得到以下說明: Targets: : out/libskia.a bench: out/bench/bench tests: out/tests/tests clean: removes entire out/ directory help: this text Options: (after make, or in bash shell) SKIA_DEBUG=true for debug build SKIA_SCALAR=fixed for fixed-point build SKIA_BUILD_FOR=mac for mac build (e.g. CG for image decoding) 期望的編譯輸出就是靜態函式庫 out/libskia.a,而 Skia 的內部運算可選擇浮點數與定點 (fixed-point),不過筆者發現,目前尙未能透地選擇,但這不影響我們理解 Skia 的使用與體驗其威力。以筆者使用的 GNU/Linux 來說,可下達以下指令要求編譯: # make SKIA_BUILD_FOR=linux 沒意外的話,系統就會乖乖的編譯: compiling out/src/core/Sk64.o compiling out/src/core/SkAlphaRuns.o compiling out/src/core/SkBitmap.o ... 至於編譯 benchmark 程式,則可透過以下指令: # make SKIA_BUILD_FOR=linux bench benchmark 程式算是除了 Chromium 之外,最佳的「文件」了,不過 SKia API 本來就簡潔強大,這也不妨礙。執行 benchmark 程式: ./out/bench/bench -o `pwd` 陸續會有類似以下的輸出: running bench polygon running bench lines running bench points running bench rrects3 running bench rrects1 running bench ovals3 running bench ovals1 running bench rects3 running bench rects1 running bench bitmap_index8 running bench bitmap_4444 running bench bitmap_565 running bench bitmap_8888 可大概窺知 Skia 涵蓋的範疇,接著筆者就寫個小程式,使用 Skia C++ API: [test-skia.c] /* Simple vector graphics demo utilizing Skia toolkit. * Authored by Jim Huang
*/ #include "SkBitmap.h" #include "SkDevice.h" #include "SkPaint.h" #include "SkRect.h" #include "SkImageEncoder.h" int main() { // Declare a raster bitmap, which has an integer width and height, // and a format (config), and a pointer to the actual pixels. // Bitmaps can be drawn into a SkCanvas, but they are also used to // specify the target of a SkCanvas' drawing operations. SkBitmap bitmap; bitmap.setConfig(SkBitmap::kARGB_8888_Config, 200, 200); bitmap.allocPixels(); // A Canvas encapsulates all of the state about drawing into a // device (bitmap). This includes a reference to the device itself, // and a stack of matrix/clip values. For any given draw call (e.g. // drawRect), the geometry of the object being drawn is transformed // by the concatenation of all the matrices in the stack. The // transformed geometry is clipped by the intersection of all of the // clips in the stack. SkCanvas canvas(new SkDevice(bitmap)); // SkPaint class holds the style and color information about how to // draw geometries, text and bitmaps. SkPaint paint; // SkIRect holds four 32 bit integer coordinates for a rectangle. SkRect r; paint.setARGB(255, 255, 0, 0); r.set(25, 25, 145, 145); canvas.drawRect(r, paint); /** Draw the specified rectangle using the specified paint. The rectangle will be filled or stroked based on the Style in the paint. */ paint.setARGB(255, 0, 255, 0); r.offset(20, 20); canvas.drawRect(r, paint); paint.setARGB(255, 0, 0, 255); r.offset(20, 20); canvas.drawRect(r, paint); // SkImageEncoder is the base class for encoding compressed images // from a specific SkBitmap. SkImageEncoder::EncodeFile("snapshot.png", bitmap, SkImageEncoder::kPNG_Type, /* Quality ranges from 0..100 */ 100); return 0; } 編譯方式: g++ -I./include -I./include/core -I./include/images -Wall -o test-skia test-skia.c out/src/images/SkImageDecoder_libpng.o out/libskia.a -lpng -lpthread -g 筆者做了簡要的註解,大概可知曉 Sk 開頭的這些 API 的功用,而上述的範例程式一開始就要求 Skia 配置畫布 (SkCanvas),接著透過一份 SkRect 物件 r,給定 ARGB 的描述,使其有著不同的顏色,再來就是調整向量物件的位移並繪製。正如前文提及,Skia 僅是繪圖引擎,並未如 Cairo 一般廣泛對應到 PDF, X11, GDI 等等底層繪圖裝置,所以為了方便觀察繪圖結果,我們透過 Skia 內建的 image codec 來輸出 PNG 圖檔,所以執行前述編譯後的執行檔 "test-skia",應該會得到以下圖檔:(本無外框與底色,但為了清楚於文章呈現,額外用繪圖軟體追加) 疊合的三個不同色的矩形物件,就是透過以下 API 呼叫達成: paint.setARGB(255, 0, 255, 0); r.offset(20, 20); canvas.drawRect(r, paint); 由於 Skia 與 Cairo 的同質性相當高,也可參照 [Cairo :: documentation] 建立所需的背景知識。
查看更多
1
个回答
默认排序
按发布时间排序
撰写答案
登录
注册新账号
关注者
0
被浏览
3.5k
关于作者
bernard
这家伙很懒,什么也没写!
提问
414
回答
5940
被采纳
76
关注TA
发私信
相关问题
1
有关动态模块加载的一篇论文
2
最近的调程序总结
3
晕掉了,这么久都不见layer2的踪影啊
4
继续K9ii的历程
5
[GUI相关] FreeType 2
6
[GUI相关]嵌入式系统中文输入法的设计
7
20081101 RT-Thread开发者聚会总结
8
嵌入式系统基础
9
linux2.4.19在at91rm9200 上的寄存器设置
10
[转]基于嵌入式Linux的通用触摸屏校准程序
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
使用百度AI助手辅助编写一个rt-thread下的ONVIF设备发现功能的功能代码
2
RT-Thread 发布 EtherKit开源以太网硬件!
3
rt-thread使用cherryusb实现虚拟串口
4
《C++20 图形界面程序:速度与渲染效率的双重优化秘籍》
5
《原子操作:程序世界里的“最小魔法单位”解析》
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
keil_MDK
rt_mq_消息队列_msg_queue
at_device
ulog
C++_cpp
本月问答贡献
踩姑娘的小蘑菇
7
个答案
3
次被采纳
a1012112796
13
个答案
2
次被采纳
张世争
9
个答案
2
次被采纳
rv666
5
个答案
2
次被采纳
用户名由3_15位
11
个答案
1
次被采纳
本月文章贡献
程序员阿伟
7
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
大龄码农
1
篇文章
2
次点赞
ThinkCode
1
篇文章
1
次点赞
Betrayer
1
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部